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.
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.