0

Each WPF Image Control has RenderTransform Property that sets Scale, Skew, Rotate and many more Transformation to Images. After Calling RenderTransform Property, How to get Rendered Image into the BitmapImage or RenderTargetBitmap Class or Any other class?

This is my Code:

Dim InImage As New BitmapImage(New Uri("My Image Path"))

Dim TG As New TransformGroup
TG.Children.Add(New RotateTransform(190))

Dim MyImg As New Image
MyImg.Source = InImage
MyImg.RenderTransform = TG

'Here i need get Transformed Image into a BitmapImage or RenderTargetBitmap Variable  or Any other class variable.
GiGatR00n
  • 116
  • 8
  • No need for the TransformGroup. Just set `MyImg.RenderTransform = New RotateTransform(190)`. Then call `Measure` and `Arrange` on `MyImg`, and finally create a RenderTargetBitmap and call its `Render` method with `MyImg` as parameter. – Clemens Jul 20 '14 at 17:00
  • @Clemens Thanks `Measure` and `Arrange` is worked properly. but now the problem is that after some rotation, some part of Rotated Image not drawing. how to solve that? – GiGatR00n Jul 20 '14 at 18:16
  • Use an appropriate rectangle (with negative X and Y) in Arrange. You may also try LayoutTransform instead of RenderTransform. – Clemens Jul 20 '14 at 18:19
  • When i add **Rotated Image** to Canvas, some part of image which is placed on Left or Top of canvas, will not draw. – GiGatR00n Jul 20 '14 at 18:43

1 Answers1

2

It's a pity that TransformedBitmap does not support rotation with angle other than any multiple of 90 degs (that means we can only rotate 90, 180, 270, ...). Thinking about which objects we can put in a bitmap and apply some Transform? Well we have DrawingGroup, DrawingVisual, ImageBrush, UIElement and via DrawingContext.

  • Using DrawingGroup, we have to put in an ImageDrawing and apply the transform via the Transform property of the DrawingGroup. Then we have to use a DrawingImage, set the Drawing property to the DrawingGroup.

  • Using DrawingVisual, we have to open a DrawingContext, use the DrawImage method after pushing some transform. Then we may have to use RenderTargetBitmap by passing the DrawingVisual in the Render method.

  • Using UIElement (like your idea about using Image control as the medium), we have to render the image on the UIElement. So an Image control suits this best. Every UIElement has a Transform property allowing us to add whatever transform. At last we also have to use a RenderTargetBitmap by passing the UIElement in the Render method.

  • Using ImageBrush, we have to set the ImageSource property to a BitmapImage. Then we can use the Transform or RelativeTransform property to apply some transform. After that we have to use a DrawingImage. Create a simple GeometryDrawing using the ImageBrush as its Brush, and a RectangleGeometry as its Geometry. Finally we just need to set this GeometryDrawing to the Drawing property of the DrawingImage. The output is the DrawingImage. I would like to use this approach to write the code here:

    Dim InImage As New BitmapImage(New Uri("My Image Path"))
    Dim ImgBrush As New ImageBrush(InImage)
    ImgBrush.Viewport = New Rect(0.1,0.1,0.8,0.8)
    ImgBrush.ViewportUnits = BrushMappingMode.RelativeToBoundingBox
    Dim Rotating As New RotateTransform(190)
    Rotating.CenterX = 0.5
    Rotating.CenterY = 0.5
    ImgBrush.RelativeTransform = Rotating
    
    Dim ImgSize As New Rect(0,0,300,400)
    Dim DrawImage As New DrawingImage()
    DrawImage.Drawing = New GeometryDrawing(ImgBrush, null, ImgSize)
    

Note about the "My Image Path". I've found out that using a Relative image would not work if you don't have any Image folder at the same level with the built exe file. If you don't want to deploy some image folder together with your application, you can add your image as a Resource. To refer to an image added as a Resource in code behind, you have to use a special kind of path:

pack://application:,,,/Your_Relative_Image_Path

Note that to be sure your image is added as a Resource, try right clicking on the image (under the Projects treeview), select Properties in the popup menu, then look into the Build Action field, it should be Resource.

Also note about the ImgBrush.Viewport, setting it appropriately will prevent the image from being cut off (that's because the transformed image is rotated). It depends on the ImgSize and how much degree you rotate.

King King
  • 61,710
  • 16
  • 105
  • 130
  • after running your code, this error occurred: **Transform must be a combination of scales, flips, and 90 degree rotations**. it seams that the TransformedBitmap class dose not support full rotation or skew. – GiGatR00n Jul 20 '14 at 14:21
  • @GiGatR00n yes, `TransformedBitmap` does not support rotation other than multiples of 90degs. See my updated answer for another approach (in fact we have many approaches, I just picked a one). – King King Jul 20 '14 at 17:14
  • @GiGatR00n you're welcome. The logic is simple but you may need time to tweak it with some experiment. The most obvious/intuitive way is using `TramsfomedBitmap`, however as we know it does not work in your case, although other kinds of transform are well supported. – King King Jul 20 '14 at 17:36
  • 1
    yeah, `TransformedBitmap` not work in my program cuz i need 0-360 degree rotation. im using `DrawingGroup` and `ImageBrush`. `DrawingGroup` works properly. Thanks. – GiGatR00n Jul 20 '14 at 17:42