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

Asked By: VIshvesh

||

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
Answered By: John Anderson

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

Answered By: VIshvesh
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.