I have a function c[x] whose domain and range are both [0,1]. And I have a picture with width W, height H. Now I want the picture to be compressed horizontally, with c[x] being the compression ratio for the part of the picture whose x-coordinate is x.W. To achieve this I have to discretize c[x], which could be fussy and problematic. Besides since it's compression, it's hard to decide which row of pixels should be abandoned. So is there any good way to do this?

  • 2
    $\begingroup$ I'm not sure I understand correctly what you're asking, but try d = f /. First@NDSolve[{f'[x] == c[x], f[0] == 0}, f, {x, 0, 1}]; ImageForwardTransformation[image, {d@#[[1]], #[[2]]} &, PlotRange -> All] $\endgroup$
    – user484
    Aug 22 '14 at 16:51
  • $\begingroup$ Do you mean that the part of the image from the left to the horizontal fraction x should be compressed, and that this compressed part of the image should replace the original part of the image? Or do you just want to get the left part of the image by itself? And by compression, you do you mean that you just want a quick display of that process or you actually want a new image with the result? The difference is that the display can be done without any image manipulations (image manipulations are quite slow in Mathematica). $\endgroup$
    – Jens
    Aug 22 '14 at 17:50
  • 1
    $\begingroup$ @RahulNarain Thanks, that's exactly what I need $\endgroup$
    – arax
    Aug 26 '14 at 18:39

Here is an approach for what i think you mean that does an interpolation rather than selectively dropping columns..

 i0 = ExampleData[{"TestImage", "Lena"}];
 w = ImageDimensions[i0][[1]];
 c[x_] := ((1 + Erf[2 (4 x - 2)])/2);
 vals = Table[1 + (w - 1) c[x], {x, 0, 1, 1/200}] // N;
 Image[(Interpolation[MapIndexed[{First@#2, #1} &, #]] /@ vals) & /@ ImageData[i0]]

enter image description here

Edit: this is surprisingly 10x faster than ImageForwardTransformation ( I never used that before though so i'm not sure I've got it right )

Edit2: This is in fact faster than my interpolation...

 ImageTransformation[i0, {c[#[[1]]], #[[2]]} &   , {200, 512} ]

(The result is very close but not identical)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.