I do not think I can document the magic. There are many variables. I suggest people not to overthink and try things to find what works for them. I am not really following this thread since I found it too confusing. You are really surprised that different implementations (crop source, affine, gimp) and combinations give different results? Or you are not, but want a full explainer? There’s too many variables involved. I will add a few hints here, but not sure about adding to the documentation yet. Maybe it can be refined to be included:
- The Crop: Source filter removes rows and columns from the edges of an image before anything else implied or not.
- There is implicit scaling (upstream from all user-added filters) from the source resolution to the project resolution that maintains the source aspect ratio by padding with black. But on the rare occasion a downstream filter can bypass this or govern its target resolution.
-
Size, Position & Rotate (aka affine transform) has different behaviors depending upon:
- If Preview Scaling is on:
→ tell upstream to scale to Size with the preview scaling factor applied. - If there is more than one of this filter on the same object, or
- if Size mode is Fill, or
- if Size mode is Distort, or
- if the source image is larger than Size (down-scaling):
→ tell upstream to scale to Size - Otherwise (one transform filter on this clip), Size mode is Fit, and source is smaller than Size:
→ bypass the upstream scaler.
- If Preview Scaling is on:
- Size, Position & Rotate uses interpolation when mapping source pixels to each destination pixel.
In stack #3, you would expect the image to be initially scaled to 608x1080; however, the two filters are compounding such that the first filter thinks there is preview scaling at 3413p (316% zoom = 1919x3413). Thus, the first filter behaves under the preview scaling rule above because the second filter asked it for 1919x3413. The way preview scaling works at the engine level is different than the user presentation within Shotcut. In Shotcut there is a global setting but not so in the engine. A filter in the engine receives an image request at a resolution (typically at video mode with preview scaling applied), compares it with the current video mode resolution, and scales its parameters accordingly. Since the second transform filter is requesting 1919x3414 and the video mode is 1920x1080, it scales its size parameter by ~3.16x. Thus, the first filter ends up also requesting 1919x3414 from the upstream scaler. I have no plans to change or address any of that. Basically, I do not know how and lack the confidence to do so without breaking a use case or backwards compatibility.
Before version 20.09 IIRC the Size, Position & Rotate filter would always bypass the upstream scaler and do its own scaling, but that gave very poor quality for down-scaling and was changed.