WPF Image, how to remove blur? - wpf

I have
I need
XAML:
<Image Height="500"
MouseLeftButtonDown="image_MouseLeftButtonDown"
MouseRightButtonDown="image_MouseRightButtonDown"
Name="image"
Stretch="Fill"
Width="500" />`
C#:
wbmap = new WriteableBitmap(50, 50, 500, 500, PixelFormats.Indexed8, palette);
wbmap.WritePixels(new Int32Rect(0, 0, wbmap.PixelWidth, wbmap.PixelHeight), pixels, wbmap.PixelWidth * wbmap.Format.BitsPerPixel / 8, 0);
image.Source = wbmap;

As tkerwin mentioned, change the BitmapScalingMode to NearestNeighbor in you XAML Image code:
RenderOptions.BitmapScalingMode="NearestNeighbor"

Perhaps you need to change the bitmap scaling mode to nearest neighbor.
Add RenderOptions.BitmapScalingMode="NearestNeighbor" to your Image tag.

Increase resolution / scale without anti-aliasing.
Whats happening is WPF is scaling the image but "averaging" the pixels, rather than doing a more blocky scale.
See this post:
Resize bitmap like in MS Paint

Related

In WPF what is the proper method for drawing a line and PNGs on a bitmap that is attached to a canvas?

I don't do that much with WPF anymore and I always seem at a loss for the most basic things. I've tried the Googles but they're not helping.
I've got a canvas (maybe I shouldn't use a canvas?) and I want to attach an image. The only way that I could find to do this was like so:
<Canvas Grid.Column="2" HorizontalAlignment="Right" Height="822" VerticalAlignment="Top" Width="1198" Name="MainCanvas">
<Canvas.Background>
<ImageBrush ImageSource="/MapDesignModule;component/MapFrame.bmp" Stretch="None" AlignmentY="Top" AlignmentX="Right"/>
</Canvas.Background>
</Canvas>
Now, I need to draw lines on the image attached to the canvas (later I will also have to place transparent PNGs, or BMPs with white set to Alpha 0, on the image as well).
In the past I would get a writeablebitmap from the image.source but you apparently can't do that from an ImageBrush?
What is the 'proper way' to put an image on the screen and draw and blit images onto it?
Just put multiple Image and Line elements on top of each other in a common Panel, e.g. a Canvas:
<Canvas>
<Image Source="/MapDesignModule;component/MapFrame.bmp" />
<Image Source="/MapDesignModule;component/Overlay.png" />
<Line X1="100" Y1="100" X2="200" Y2="200" Stroke="Black" />
</Canvas>
You could also assign a name to the Canvas
<Canvas x:Name="canvas">
to access it in code behind:
canvas.Children.Add(new Image
{
Source = new BitmapImage(new Uri(
"pack://application:,,,/MapDesignModule;component/MapFrame.bmp"))
});
canvas.Children.Add(new Line
{
X1 = 100,
Y1 = 100,
X2 = 200,
Y2 = 200
});
In case you later want to add multiple shape overlays, you may consider using an ItemsControl with an appropriate view model, e.g. as shown here: https://stackoverflow.com/a/40190793/1136211

Crop an Image in WPF

Give an image:
Image tileSet = new Image();
tileSet.Source = new BitmapImage(new Uri(#".."));
How can i cropt it, defining a rectangle area?
You can use CroppedBitmap for that
var fullBitmap = new BitmapImage(new Uri(#".."));
tileSet.Source = new CroppedBitmap(fullBitmap, new Int32Rect(0, 0, 100, 100));
To build a little on dkozl's answer above,
I found the DPI of the original image to crop and the DPI of the display were creating an "offset" of where I was intending to crop the original image.
The "offset" can be corrected by matching the image Width and Height in pixels with the DPI of the screen, instead of letting the Image element to it's own automatic sizing.
You do this by setting the Stretch to None, and the Width & Height of the image as below:
<Image
x:Name="imageToCrop"
Stretch="None"
Width="{Binding Source.PixelWidth,RelativeSource={RelativeSource Self}}"
Height="{Binding Source.PixelHeight,RelativeSource={RelativeSource Self}}"/>

Get scaling factor of an image when the image goes out of grid

I have a grid that contains an image.
<Grid Name="grid1">
<Image Name="image1" Stretch="None" Source="C:\Users\User\Desktop\image.jpg"/>
</Grid>
If the size of image was greater than the size of the grid, I want to scale it manually by render transform to fit the grid. I don't want to use Stretch="Fill" because I need the scale factor.
Is there any way to detect the situation that an UIElement goes out of view?
I need your help.
You could simply set the Stretch property to Uniform (or perhaps Fill) and calculate the scaling factor from the ActualWidth of the Image and the Width of the ImageSource, whenever you need it. The sample below does the calculation in a SizeChanged handler, but it could be anywhere else.
<Image Name="image1" Stretch="Uniform" Source="C:\Users\User\Desktop\image.jpg"
SizeChanged="ImageSizeChanged"/>
The calculation looks like this:
private void ImageSizeChanged(object sender, SizeChangedEventArgs e)
{
var scale = image1.ActualWidth / image1.Source.Width;
}
As Uniform is the default value of the Stretch property, you wouldn't have to set it at all.
I'm not sure why you would want to rescale your image manually when WPF can do it for you...
Instead of putting the image straight into the grid, use a Viewbox control:
<Grid Name="grid1">
<Viewbox>
<Image Name="image1" Stretch="None" Source="C:\Users\User\Desktop\image.jpg"/>
</Viewbox>
</Grid>
The Viewbox will automatically scale the picture to fit inside the grid...

How to zoom image inside rectangle WPF

I am trying to zoom in and out image inside Rectangle control. But while doing so my entire Rectangle is getting zoomed in instead of just image inside that. for doing so I am using ScaleTransform and TranslateTranform on Rectangle. I should do the same on image instead of Rectangle but I dont know how? Could anyone please help me out.
XAML :
<Rectangle x:Name="LiveViewWindow" Fill="#FFF4F4F5" HorizontalAlignment="Right"
ClipToBounds="True" />
Code:
InteropBitmap m_LiveViewBitmapSource =Imaging.CreateBitmapSourceFromMemorySection(
section, width, height, PixelFormats.Bgr32, width*4, 0) as InteropBitmap;
ImageBrush m_BackgroundFrame = new ImageBrush(m_LiveViewBitmapSource);
RenderOptions.SetBitmapScalingMode(m_BackgroundFrame, BitmapScalingMode.LowQuality);
LiveViewWindow.Fill = m_BackgroundFrame;
n then for I am using Invalidate() property to render InteropBitmap to Rectangle.
You may set the Transform property of the ImageBrush. Get more information in Brush Transformation Overview.

Reduce Image resolution in WPF image control

I have a image control in WPF. I need to reduce the image size control width and height. But when i Do that , the image is not looking good. The data loss is more.
So i thought to reduce the image resolution instead of just changing the image control width and height.
can any one help me how to change the image resolution of the binded image in WPF image control
[I mean image is already binded to image control now I have to the change the resolution only]
In .NET 4 they changed the default image scaling to a low quality one...so you can use BitmapScalingMode to switch back to the higher quality one:
<Image RenderOptions.BitmapScalingMode="HighQuality"
Source="myimage.png"
Width="100"
Height="100" />
http://10rem.net/blog/2010/05/01/crappy-image-resizing-in-wpf-try-renderoptionsbitmapscalingmode
You can also combine the above with other options like the Decode options if your source image is a huge image (this just reduces memory usage in your application).
http://www.shujaat.net/2010/08/wpf-saving-application-memory-by.html
other options to prevent "blurryness" is to put UseLayoutRounding="True" on your root element (i.e. Window)....it's recommended to use this in .NET 4 rather than SnapToDevicePixels:
When should I use SnapsToDevicePixels in WPF 4.0?
http://blogs.msdn.com/b/text/archive/2009/08/27/layout-rounding.aspx
You can use the DecodePixelWidth property like this:
<Image Stretch="Fill">
<Image.Source>
<BitmapImage CacheOption="OnLoad" DecodePixelWidth="2500" UriSource="Images/image.jpg"/>
</Image.Source>
</Image>
1) Have a try with a ViewBox : put your image within a ViewBox.
2) Sometimes the rendering engine looses quality because of pixel alignement issues, especially on low-resolution device. Have a look to SnapsToDevicePixels property, and try to set it to true in the containing control AND / OR in the ViewBox.
3) Obviously you could write a Control that perform a resolution change but it is quite some work.
Try this.
Image img = new Image();
var buffer = System.IO.File.ReadAllBytes(_filePath);
MemoryStream ms = new MemoryStream(buffer);
BitmapImage src = new BitmapImage();
src.BeginInit();
src.StreamSource = ms;
src.DecodePixelHeight = 200;//Your wanted image height
src.DecodePixelWidth = 300; //Your wanted image width
src.EndInit();
img.Source = src;

Resources