Metro App stretch="fill" results in poor quality - c#

In WPF I could do RenderOptions.BitmapScalingMode, but this isn't available in Metro apps. Is there a way I can get better quality scaling when I scale an image down?

You shouldn't use Fill for Stretch property if you want your image to keep its initial ratio.
Use Uniform, or UniformToFill.
More info here :
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.image.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.image.stretch.aspx
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.media.stretch.aspx
Next, on the subject of scaling down an Image, there already is an answer here : High quality image scaling.
Basically, use DecodePixelHeight or DecodePixelWidth, or better, use a different source image.
http://msdn.microsoft.com/en-us/library/windows/apps/hh465362.aspx
Don’t use larger images that are scaled down Larger images that are scaled down show scaling artifacts and jagged edges on standard tablets. Photographs are the only exception as they can look good when scaled down. You should ensure that your images look great on the 100% scale using the above guidance.

Related

C# Fast load Bitmap into PictureBox

I receve Bitmap image from a camera at 30 fps, and I need to display all images in a pictureBox.
The problem is that the PictureBox is very slow!
I have try to implement a custom PictureBox with DoubleBuffer enabled but the problem is not resolved.
Do you have a custom PictureBox or an user control or a solution that can display the image faster?
Additional information:
The image resolution is 2048x1088 with 256 graylevel (8bit image).
I use AForge.NET for elaborate the images.
Thank you
That image gets expensive to draw when it has to be resized to fit the PB's client area. Which is very likely in your case because your images are pretty large. It uses a high-quality bi-cubic filter to make the resized image look good. That's pretty expensive, albeit that the result is good.
To avoid that expense, resize the image yourself before assigning it to the Image property. Make it just as large as the PB's ClientSize.
That's going to make a big difference in itself. The next thing you can do is to create the scaled bitmap with the 32bppPArgb pixel format. It's the format that's about 10 times faster then any other because it matches the video adapter on most machines so no pixel format conversions are necessary.

How to get a ScrollViewer to zoom in to see individual pixels?

I'm making an app for Windows 8.1 where it is important to be able to zoom in and examine images in detail. If I just open up the bitmap and zoom in it looks like.
However when I load the image into my app and use the ScrollViewer to zoom in I get.
As it appears to be trying to interpolate pixel values for some sort of anti-aliasing.
How can I get it so that when I zoom in it shows (as best it can) the exact pixels of the image? In particular I'm using the image as the background to a canvas which is contained in a scroll viewer.
I've looked around on here and MSDN and found a pair of related questions, but as yet they don't seem to have solved my exact problem.
A discussion on WPF
A similar issue with a canvas
Older related question on pixel art
A way to use bitmap encoding (which I couldn't get to work)
Similarly phrased question
There is no easy way to go about this, your best option is to use DirectX to render the image much larger so that you can mitigate the effect of WinRT automatically interpolating pixel values.
As someone explained on MSDN and based on this outstanding request I can't see any other way to accomplish this.
Use Win2D
Win2D is a DirectX inter-op library for WinRT. With this you can render the image at a much larger size, and then set the default zoom level for the scrollViewier to be very small. Because of this when you zoom in it will appear to be that you can see the individual pixels without any fuzzy/blurry interpolation because you will actually be seeing groups of 64 pixels or so all as one color. I couldn't find any way to actually override what kind of interpolation gets done so this seems to be the best method.
Download Win2D as a NuGet package using Visual Studio, Win2D's
quickstart guide does a good job explaining some of the setup
Set up your canvas and the draw event and use the DrawImage function to render the image larger
<ScrollViewer x:Name="Scroller" ZoomMode="Enabled"
MinZoomFactor="0.1" MaxZoomFactor="20">
<canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" CreateResources="create"/>
</ScrollViewer>
In the canvas_draw function.
canvas.Width = original.Width * 10;
canvas.Height = original.Height * 10;
args.DrawingSession.DrawImage(bitmap,new Rect(0,0,original.Width*10,original.Height*10), new Rect(0,0,original.Width,original.Height), 1.0f, CanvasImageInterpolation.NearestNeighbor);
Make sure to set your canvas to be larger as well
In your code behind set the default zoom of your ScrollVieiwer to be appropriate so your image appears to be the same size.
In the page constructor
Scroller.ZoomToFactor (0.1f);
Other Ways Which I Looked Into and Didn't Work
Making the canvas very large and using BitmapEncoder/BitmapDecoder with the interpolation mode set to NearestNeighbor, this introduced lots of visual artifacts even when scaled to a power of 2 size
Render options only appear to be usable in WPF and not WinRT
It may also be possible to use some image manipulation library to simply make the bitmap 10x or so as large and then use that, but I ended up using Win2D instead.

2d Graphics advantages & disadvantages over 2d Images in WPF

I need to know whether there is any advantages or disadvantages on using 2d graphics in wpf over 2d images or not?
I mean if I'm going to display an ellipse in a wpf window which one is more useful and why? To create an Ellipse object or to create an Image control and then load an pre-designed ellipse image into it?
Does using 2D graphics have any advantages in the sense that they consume less memory or increase performance or anything like that?
Thanks in advance.
An Image is not realy good scalable.
An vector Graphics is.
On a high dpi display your Image with Width = 300 (Units not pixels) and Height = 300 (units) is on a Display with 96 dpi not bigger than a Display with 144dpi. But the Image on the 144 dpi display needs more Pixels for the same size.
1 Unit is 1/96 inch.
So it is better to have a scalable "image" than a fixed one.
Its one of the features of wpf that winform don't have! and the reason why you should not use Pixels as a Size / Width / Height / Position / etc.
Excursus:
In winform it is hard to programm a scalable programm. on high dpi monitors the font, buttons etc. looks very small. there was no option to solve this problem.
so windows programmed an algorithm that creates a bitmap of the programm and scales this up.
So: the progamms width and height is the same as before, but the user sees a much bigger one (the Bitmap). The user input is then recalculated on the real sized application; Everything is working fine - and looking fine.
Hope that helps and is correct.

Camera Output in fullscreen - Windows Phone

I'm working on augmented reality and I wanted to know if it was possible to get the camera output in fullscreen with a normal scale. I'm currently able to get a deformed output (everything is larger than in the real world).
Edit:
I found in the PhotoCamera class on msdn that I have to use camera.AvailableResolutions. This returns an IEnumrable of Size, each one being a supported resolution.
Based on your comment:
I do not understand this. Do you mean to say that the aspect ratio is
wrong; squares becoming rectangular? Could it be that you are
displaying/stretching the picture incorrectly?
Yeah that's what I mean, the image is stretched because the camera is taking an image in 640x480 and the screen is in 800x480
In the UI where you display the image, set the Stretch to None, Uniform or UniformToFill. Do not use Fill that will distort the image.
<Image Source="..." Stretch="Uniform" />
See these examples on the MSDN
Each phone has different lens focal length and screen size. There is no API to scale camera output to physical dimensions of real world (to see the world on the screen like through transparent window). Also, the distance from user eyes to the phone is affected to what should be displayed. You could experimentally find average scale factor to best map camera output to phone screen.
EDIT:
From the beginning it was like the question was not about distortions on different screen orientations but like augmented reality problem.

How can I resize an image in C# while retaining high quality?

I found an article on image processing from here: http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing Everything works fine.
I want to keep the high quality when resizing the image. I think if I can increase the DPI value I can achieve this. Does anyone know if this is possible? And if so, how can I implement it in C#?
For starters, it's worth pointing out that there are two general categories of images; vector [e.g. SVG, WMF, Adobe Illustrator and Corel Draw Graphics] and bitmap (also called raster) images [e.g. Bitmap, JPEG and PNG Images].
Vector images are formed from a series of mathematical equations and/or calculations. Bitmap images, on the other hand, are made up of individual dots (pixels) each corresponding to a particular feature on the object the image is taken of.
If it should happen that you want to resize an image, the first thing to consider is if it is a bitmap or vector image. By virtue of the fact that vector images are obtained from calculations, they can be perfectly resized without losing any detail. The case is different for bitmap images. Since each pixel is independent of the other, when you desire to resize it, you are simply increasing or decreasing the source to target pixel ratio.
So in order to double the size of a vector image, simply multiply the target dimensions by two and everything comes out all right. If you should apply the same effect on a bitmap, you are actually increasing each source pixel to cover four pixels (two rows of two horizontal pixels).
Of course, by applying interpolation and filtering, the computer can "smooth" out the edges of the target pixels so they seem to blend into each other and give the appearance of a reasonably resized image but this output is never the same as resizing a vector image; vector images resize perfectly.
You also mentioned DPI in your question. DPI is essentially the number of pixels that correspond to an inch when the image is printed not when it is viewed on a screen. Therefore by increasing the DPI of the image, you do not increase the size of the image on the screen. You only increase the quality of print [which needless to say depends on the maximum resolution of the printer].
If you really desire to resize the image and the image is a bitmap, as a rule of thumb, do not increase the size beyond 200% of the original image's size else you'll lose the quality.
You can see this answer for code to resize bitmap images.
To see a sample vector image, go to this link.
Note Try zooming in and out of the image to see how well it resizes.
A typical bitmap are the StackOverflow sprites. They do not keep their quality resized.
Further Reading
Vector Graphics: http://en.wikipedia.org/wiki/Vector_image
Bitmap Graphics: http://en.wikipedia.org/wiki/Bitmap_image
Simply If the original image is smaller then the re-sized image then there is hardly anything you can do. Rest is a research problem.
This would only be possible if it's a vector graphic. Look into SVG. Otherwise, I think you might need Silverlight or Flex for that part.
What you're asking isn't really possible. You can't enlarge an image while maintaining the same quality.
If you think about an image as a mapped array of pixels (literally, a "bit-map"), this makes sense. The image is saved with a fixed amount of data, and that's all you have to work with when you resize it. Any examples to the contrary (like TV shows, as suggested by one of the comments) are purely fictional.
The best that you can do is set the InterpolationMode property of the Graphics object you're using to do the resizing to "HighQualityBicubic", which is the highest quality smoothing algorithm supported by GDI+ and in fact by every major graphics package on the market. It's the best that even Adobe Photoshop has to offer. Essentially, interpolation means that the computer is calculating the approximate value of the new pixels you're adding to make the image larger from the relative values of neighboring pixels. It's a "best guess" method, but it's the best compromise we've come up with yet.
At the very least, the resulting images won't have "jaggies" or rough, pixelated lines.
Sample code:
Graphics g;
g.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// ... insert the rest of your code here
Beyond that, it's worth noting that GDI+ (which the .NET Framework uses internally for graphics routines) works best with image sizes that are multiples of 16. So if it all possible, you should try and make the width and height of your resized images a multiple of 16. This will preserve as much of the original image quality as possible.
The ideal solution is to switch to vector graphics that can be resized at will. Instead of pixel information, they contain mathematical information used to draw or "render" the image. Read more on Wikipedia.
let's try metadata in GDI+, may be it can suit your request

Categories

Resources