0

I have an image on a canvas and a ScaleTranform and a TranslateTransform attached to the image's RenderTranform. So with a bit of mouse event handling I can move and zoom the image within the 350 by 450 bounds of the canvas.

How would I calculate the clipping rectangle on the original BitmapImage, to that of the visible area on the screen, after some scaling and translation. I'd like to crop the original BitmapImage.

<Border BorderBrush="Black" BorderThickness="2">
  <Canvas Name="canvas" ClipToBounds="True" Height="450" Width="350">
    <Image Name="image" Opacity="1" RenderTransformOrigin="0.5,0.5" Height="450" Width="350">
       <Image.Source>
          <BitmapImage UriSource="test.jpg"/>
       </Image.Source>
     </Image>
  </Canvas>
</Border>

Thanks

Terje
  • 130
  • 1
  • 9

2 Answers2

1

I would think it would be simple math to take the current ScaleTransform values and figure out what the actual size of the image is at the time, and then you know that you have a 350x450 box that you're going to crop out of that, you just need to use the current TranslateTransform to figure that out. Just keep in mind what you're using for the origins of these transforms, as that's what you need to calculate it from.

What I said above assumes that you have the ScaleTransform first in your RenderTransform and the TranslateTransform second. The order of operations does matter here.

Tim
  • 14,999
  • 1
  • 45
  • 68
  • Thanks for the tip about "the order does matter". As I wrote @santa there is the extra dimension, that the 350x450 box is just some values which indicates how big the box is on the screen. If I put a 1000x5000 pixel picture in the box it would still fit in the box as default, until you start messing with the scale. This makes it less trivial (for me at least). – Terje May 17 '11 at 18:35
  • Hrm... does the image always actually "fill" the box? In other words, is the aspect ratio of the image always the same as the aspect ratio of that box? – Tim May 17 '11 at 18:43
  • It's a uniform fill, so the aspect ratio of the image is that of the image, regardless of the box. So at start there is a white border at top and bottom or left and right depending on the image aspect ratio. – Terje May 17 '11 at 19:43
  • You meant that it's Uniform, not UniformToFill, right? Just clarifying. I think you can still do this, but its a lot of math to get it right. I don't think there's a built-in way of figuring it out as you mentioned to Santa below. I'm going to take a stab at the math and see what I can come up with. – Tim May 17 '11 at 19:58
0

Simply apply the calculations done to the Image by the Transformations to the bounds... (And do it in the same order...)

So if you Scale it up by a factor of 2 in X and Y the resulting Canvas will be 450/2 x 350/2 (in size - origin is still unknown)

And i guess it would be easier to avoid the TranslateTransform and simply play with the Origin of the ScaleTransform... whereas an Origin of 0 should give you an Clip-origin of 0 and a X&Y Origin of 1 will result in the image to be lower right...

so to set up some simple formula..:

double W = 450;
double H = 350;

double SX = 2;
double SY = 2;

double OX = .3;
double OY = .3;

double newW = W / SX;
double newH = H / SY;

double newX = (W-newW) * OX;
double newY = (H-newH) * OY;

so newX,Y,W and H contain the data you are looking for!

regards, dave

santa
  • 983
  • 9
  • 30
  • Thanks, but I don't feel it is quite that simple. The 350 by 450 is just the size of the "clipping" area (the canvas). The image can be like any dimension in pixels, and is still shown within the "clipping" area as default (that is when scaling is 1 and no translation). I just thought that there might have been a build in way to map "what is shown on the screen" which is pixel independent in WPF, to the actual pixel coordinates in the source image. – Terje May 17 '11 at 18:27
  • wouldn't be that hard to adapt either... can you provide a simple dummy-project with an comment where you'd like to get the visible area? i could throw a few lines source onto it... – santa May 18 '11 at 10:32