How do I make an image resize from a fixed point
Question:
so I’m making an app using kivy and python. I want the user to be able to scroll the mouse wheel and the image to resize from that fixed point. what I mean is that the position of the particular pixel on which the mouse it should be the same after the resize. Like when you zoom in an image in a photo viewing app.
Thank you in advance
# Zooming out
def zoom_out(self, pos):
self.size_multiplier -= .01
# Getting new values so that we can use them later
new_width = self.parent.width * self.size_multiplier
new_height = self.parent.height * self.size_multiplier
self.x = pos[0] - ((pos[0] / self.parent.width) * new_width)
self.y = pos[1] - ((pos[1] / self.parent.height) * new_height)
in here pos is the mouse position
the size multiplier is the percentage the image is resized
we get the new width and height
and we get where the image’s position should be like this:
- we first get percentage of the mouse on the previous sizes
- we then multiply it with the new width and height
- then we subtract that from the mouse position
idk what i am getting wrong
Answers:
One approach is to use the ScatterPlane
to contain the Image
that you want to zoom in or out. See the documentation. Here is an example:
class MyScatter(ScatterPlane):
scale_down = ObjectProperty(Matrix().scale(.9, .9, .9))
scale_up = ObjectProperty(Matrix().scale(1.1, 1.1, 1.1))
def on_touch_down(self, touch):
if touch.button == 'right' or not self.do_scale:
return super(MyScatter, self).on_touch_down(touch)
else:
if self.do_scale and self.collide_point(*touch.pos):
if touch.is_mouse_scrolling:
if touch.button == 'scrolldown':
self.apply_transform(self.scale_down, anchor=touch.pos)
elif touch.button == 'scrollup':
self.apply_transform(self.scale_up, anchor=touch.pos)
# grab the touch so we get all its later move events for sure
self._bring_to_front(touch)
touch.grab(self)
self._touches.append(touch)
self._last_touch_pos[touch] = touch.pos
return True
Ok so I just removed the ScatterPlane and tried working on my original algorithm and after some fixes it works.
def apply_transform(self, type, value, anchor):
if type == 'scale':
# Original value calculating
original_width = self.image_holder.width
original_height = self.image_holder.height
original_pos = self.image_holder.pos
# What percent of the image does the mouse cover
percentage_distance_x = (anchor[0] - original_pos[0]) / original_width
percentage_distance_y = (anchor[1] - original_pos[1]) / original_height
# Afterwards
new_width = self.image_holder.width * value
new_height = self.image_holder.height * value
# We just multiply that percentage with the new_width and subtract
# It from the mouse_pos
card_pos_x = anchor[0] - (percentage_distance_x * new_width)
card_pos_y = anchor[1] - (percentage_distance_y * new_height)
# Setting the value
self.image_holder.x = card_pos_x
self.image_holder.y = card_pos_y
self.image_holder.width = new_width
self.image_holder.height = new_height
So this works by taking a scale by which to multiply (.9 if you are scaling down or 1.1 if you are scaling up) and an anchor which is the mouse position and that do this math on it and it works. I’ll now work on Panning the image to and I will edit this after I get that also working
so I’m making an app using kivy and python. I want the user to be able to scroll the mouse wheel and the image to resize from that fixed point. what I mean is that the position of the particular pixel on which the mouse it should be the same after the resize. Like when you zoom in an image in a photo viewing app.
Thank you in advance
# Zooming out
def zoom_out(self, pos):
self.size_multiplier -= .01
# Getting new values so that we can use them later
new_width = self.parent.width * self.size_multiplier
new_height = self.parent.height * self.size_multiplier
self.x = pos[0] - ((pos[0] / self.parent.width) * new_width)
self.y = pos[1] - ((pos[1] / self.parent.height) * new_height)
in here pos is the mouse position
the size multiplier is the percentage the image is resized
we get the new width and height
and we get where the image’s position should be like this:
- we first get percentage of the mouse on the previous sizes
- we then multiply it with the new width and height
- then we subtract that from the mouse position
idk what i am getting wrong
One approach is to use the ScatterPlane
to contain the Image
that you want to zoom in or out. See the documentation. Here is an example:
class MyScatter(ScatterPlane):
scale_down = ObjectProperty(Matrix().scale(.9, .9, .9))
scale_up = ObjectProperty(Matrix().scale(1.1, 1.1, 1.1))
def on_touch_down(self, touch):
if touch.button == 'right' or not self.do_scale:
return super(MyScatter, self).on_touch_down(touch)
else:
if self.do_scale and self.collide_point(*touch.pos):
if touch.is_mouse_scrolling:
if touch.button == 'scrolldown':
self.apply_transform(self.scale_down, anchor=touch.pos)
elif touch.button == 'scrollup':
self.apply_transform(self.scale_up, anchor=touch.pos)
# grab the touch so we get all its later move events for sure
self._bring_to_front(touch)
touch.grab(self)
self._touches.append(touch)
self._last_touch_pos[touch] = touch.pos
return True
Ok so I just removed the ScatterPlane and tried working on my original algorithm and after some fixes it works.
def apply_transform(self, type, value, anchor):
if type == 'scale':
# Original value calculating
original_width = self.image_holder.width
original_height = self.image_holder.height
original_pos = self.image_holder.pos
# What percent of the image does the mouse cover
percentage_distance_x = (anchor[0] - original_pos[0]) / original_width
percentage_distance_y = (anchor[1] - original_pos[1]) / original_height
# Afterwards
new_width = self.image_holder.width * value
new_height = self.image_holder.height * value
# We just multiply that percentage with the new_width and subtract
# It from the mouse_pos
card_pos_x = anchor[0] - (percentage_distance_x * new_width)
card_pos_y = anchor[1] - (percentage_distance_y * new_height)
# Setting the value
self.image_holder.x = card_pos_x
self.image_holder.y = card_pos_y
self.image_holder.width = new_width
self.image_holder.height = new_height
So this works by taking a scale by which to multiply (.9 if you are scaling down or 1.1 if you are scaling up) and an anchor which is the mouse position and that do this math on it and it works. I’ll now work on Panning the image to and I will edit this after I get that also working