In GIMP, I want to be able to scale an image non-linearly on the horizontal axis. The perspective and mapping tools don't work for this because they change the image vertically for the perspective. The image below illustrates what I'm after. I'd appreciate any guidance!
2 Answers
There's in the basic GIMP configuration filter Distort > Spherize. In horizontal mode it deforms your image like it was used as a bottle label. It's definitely non-linear but you have only a little control. A custom math transformation would be better. It's discussed at the end of this answer.
Unfortunately the sparsest area is in the middle, not in the right edge. But you can temporarily insert a blank right half to your canvas.
Remember to set the layer size to cover the full canvas. In GIMP layers are only as big as they have content if one doesn't set the size of the layer.
Arbitary nonlinear expressions can be applied for ex. with G'MIC filter package. It has in part "Deformations" filter Cartesian Transform.
An example; the original image:
Filter dialog:
You write formulas for the coordinates of the point in the original image from where the content is taken to the result point (x,y). Formulas are probably Python language math expressions (not sure). Parameters w and h are available for the width and the height pixel dimensions of the image. You need them to match the edges.
To get something which resembles your own drawing you can write for x expression w*f(x/w) where f=any function which between 0 and 1 has the following properties
- f(0)=0 and f(1)=1
- continuous, grows monotonically
- its derivative decreases monotonically.
an example with this idea:
formula for x: w*(1-exp(-x/w))/(1-exp(-1))
formula for y: y
the original:
the result:
You mentioned you tried perspective grid which unfortunately scaled both x and y. The next x-formula gives all possible from right to left watching one dimensional perspective grid type scalings with different values of parameter A. It must be a positive number, greater than zero
formula for X: w * (A+1) * X/(A * W + X)
formula for Y: Y
too small A say A=0.1, makes the result too dense for a bitmap image in the left and too big A, say A=3, makes the effect uselessly mild. The previous maze image is scaled with A=1:
I have G'MIC installed in Krita, but it's available also for GIMP and Paint.NET.
-
Hard to say what language they are as it looks the same in c, java, javascript, rust, c#, python, and in most functional calculators. Math expressions are just that math.– joojaaCommented Jul 14, 2020 at 14:20
-
Distort -> Spherize was exactly what I was looking for, vertical instead of horizontal in my case but that's simply a selectable option. Thank you!– LucCommented Oct 17, 2022 at 11:47
Such transforms are mathematically difficult to define. If your transform is a sine/cosine law, you can use the filters that project your layer to a cylinder (Filters>Map>Map object and map to cylinder).
For an arbitrary transform, possibly using a displace map, but the actual map may be difficult to come up with:
To create the displace map (#2):
- Create a black-to-white gradient across the image
- Use curves to change it to a grey-to-white-to-grey gradient (the plain bilateral gradient doesn't work well)
If on the other hand you just want to create a grid, instead of compressing a regular grid you can generate a path, the ofn-path-inbetweener
script will generate intermediate paths between two paths, with a square or cosine law. A side effect is that the bars have the same width: