AUTOMATIC1111 / stable-diffusion-webui

Stable Diffusion web UI
GNU Affero General Public License v3.0
139.82k stars 26.5k forks source link

[Feature Request]: support simple crop anchor #16007

Open bluelovers opened 3 months ago

bluelovers commented 3 months ago

Is there an existing issue for this?

What would your feature do ?

something like photoshop can choose anchor when resize crop

image

this will easy help for some input image aspect ratio is very diff with target size

Proposed workflow

  1. Go to ....
  2. Press ....
  3. ...

Additional information

No response

bluelovers commented 3 months ago

something like this

code from Tabnine AI

def resize_image(resize_mode, im, width, height, upscaler_name=None, crop_anchor=(0.5, 0.5)):
    """
    Resizes an image with the specified resize_mode, width, height, and crop_anchor.

    Args:
        resize_mode: The mode to use when resizing the image.
            0: Resize the image to the specified width and height.
            1: Resize the image to fill the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, cropping the excess.
            2: Resize the image to fit within the specified width and height, maintaining the aspect ratio, and then center the image within the dimensions, filling empty with data from image.
        im: The image to resize.
        width: The width to resize the image to.
        height: The height to resize the image to.
        upscaler_name: The name of the upscaler to use. If not provided, defaults to opts.upscaler_for_img2img.
        crop_anchor: The point from which the image should be cropped. The values should be between 0 and 1, representing the x and y coordinates of the anchor point. The default value is (0.5, 0.5), which represents the center of the image.
    """

    #... (existing code)

    elif resize_mode == 1:
        ratio = width / height
        src_ratio = im.width / im.height

        src_w = width if ratio > src_ratio else im.width * height // im.height
        src_h = height if ratio <= src_ratio else im.height * width // im.width

        resized = resize(im, src_w, src_h)
        res = Image.new("RGB", (width, height))

        # Calculate the coordinates of the crop box based on the crop_anchor
        x_offset = int(crop_anchor[0] * (resized.width - src_w))
        y_offset = int(crop_anchor[1] * (resized.height - src_h))

        res.paste(resized, box=(width // 2 - src_w // 2 - x_offset, height // 2 - src_h // 2 - y_offset))

    #... (existing code)