Image smoothing in UWP app - c#

I have a small UWP application that load same image in two ways:
var folder = Package.Current.InstalledLocation;
var file = await folder.GetFileAsync("TestImage.png");
var bitmapImage1 = new BitmapImage();
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
await bitmapImage1.SetSourceAsync(stream);
}
var bitmapImage2 = new BitmapImage(new Uri(BaseUri, "TestImage.png"));
_image.Source = bitmapImage1;
//_image.Source = bitmapImage2;
The problem is that Image control shows the same image in different ways. For bitmapImage1 image is not smoothed, but for bitmapImage2 it's ok. How it looks like. I need to do some manipulation with image before show (change some pixels) but I also need to have smoothed image after that. Could you please help me with it?
I also used WriteableBitmap to change some pixels and have same result (not smoothed). Looks like I need to tell to Image control how to draw this.
Here is link to project for more information

I tested your code on my side. And you will found if you don't set the Height and Width properties for the image control, the pictures will looks all the same. So the reason for one looks smooth but another looks not is the image control scaling the picture. Without scaling the picture will not looks different. I guess this may be leaded but difference between vector and bitmap image.
You should be able to resolve it by create a smooth picture with the size you just want to show in the app, and set the image control to the same size with the picture or without setting the Height and Width properties, this may resolved.
My result:

I've got solution on another thread.
If change order of code lines it helps:
var folder = Package.Current.InstalledLocation;
var file = await folder.GetFileAsync("TestImage.png");
var bitmapImage1 = new BitmapImage();
_image.Source = bitmapImage1;
using (var stream = await file.OpenAsync(FileAccessMode.Read))
{
await bitmapImage1.SetSourceAsync(stream);
}
So we should assign Image source and than set source stream to Bitmap.
It seems, Image control decodes the picture quite flexibly so that it can suit for acutal UI size. If you set the BitmapImage to Image.Source first, the picture is to be smoothed properly like the second one.

Related

C# WPF when image is loaded the width and height are switched

In WPF c# loading an image from code in runtime, some images are loading when the width and height are switched so the width=height and height=width so the image is turned in 90 degrees.
In the file system properties tab, the Width and Height are correct and the image is shown correctly. If I open this image in any imageViewer the image is shown correctly but if I open it in powerpoint the same issue is found and the image is turned.
I downloaded some other codes in WPF and all are showing the image turned.
most images are shown correctly.
For example This Image :
https://www.dropbox.com/s/5fki0ew3gt78myi/TestImage_Widht4000_Height6000.JPG?dl=0
The Widht=4000and Height=6000 but if I get the bitmap.PixelWidth=6000 and bitmap.PixelHeight=400
Can anyone please help!
Thanks
I have tried everything :(
var ImagefilePath = SelectedImagePath + "\\" + ((object[])(e.AddedItems))[0].ToString();
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = new Uri(ImagefilePath.ToString(), UriKind.Absolute);
bitmap.EndInit();
// Set Image.Source
imgPhoto.Source = bitmap;
ImageInfoText.Content=" W=" + bitmap.PixelWidth + " H=" + bitmap.PixelHeight;
It is most probably the metadata within the image itself. You need to get rid of the metadata and that should fix your problem.
Here is a similar issue : WPF some images are rotated when loaded
Here is how you can remove metadata: Easy way to clean metadata from an image?
The preferable way would be to use the System.Windows.Media.Imaging.BitmapEncoder class's Metadata collection property.

Lumia imaging crop filter

Hi so I'm making an app for Windows 10 that requires a user to choose an image and it's going to crop the image to 310*128. I got the file picker code already. But I want to know how to actually crop and save the image and display in image box. I already have the xaml page done
With Lumia Imaging SDK you can both crop the selected image and resize the image. In this answer I assume you actually want to crop, but from the text I could just as well guess you really just want to resize.
For crop, use the CropEffect from Lumia.Imaging.Transforms. Set the CropArea property on it to the object, and then render it. If you are rendering straight to the XAML page I recommend using a SwapChainPanel object in XAML and a SwapChainPanelRenderer to render on it.
Given that you are loading a StorageFile and rendering to a SwapChainPanel your code might look like something like this:
StorageFile file = ...
using (var source = new StorageFileImageSource(file))
using (var crop = new CropEffect(source, new Rect(0, 0, 310, 128))
using (var renderer = new SwapChainPanelRenderer(crop, YourSwapChainPanel))
{
await renderer.RenderAsync();
}

.NET C# - Both Bitmap and Image Loads Images Smaller than Expected

I'm trying to process the typical 16 megapixel images from a modern camera. Picking a random image, both the file system and my image editing software says the image is 4608 x 3456. When I load the image in C# (VS2013 .Net 4.5) using either new Bitmap(filename) or Image.FromFile(filename), I get an image successfully loaded. However, the resulting image has a size of 1613 x 1210. Now, in some cases I want to create custom size thumbnails, and this will work ok. However, I have another need where I detect "non normal" orientations and I simply want to flip/rotate for display, then save.
Saving these images (without any adjustments, just load and save) creates a valid image on disk. However, both the file system AND my image tool says the size is 1613 x 1210.
How do I load the full size image and preserve all info back to disk? Any ideas as to what I'm doing wrong? I just want to rotate the image where needed, I don't want to shrink it!
Here's a snippet of what I tried, as promised in a comment below:
Bitmap bm = new Bitmap(fileName);
Image jpg = Image.FromFile(fileName);
jpg.Save("e:\\test.jpg");
bm.Save("e:\\test2.jpg");
Both files are smaller than their original size, and match the width and height the debugger shows for both in-memory images.
Per a suggested answer, I tried this code but saw no difference in the results:
long width = 0;
long height = 0;
byte[] imageBytes = File.ReadAllBytes(fileName);
using (MemoryStream ms = new MemoryStream(imageBytes))
{
Image jpg3 = Image.FromStream(ms);
width = jpg3.Width;
height = jpg3.Height;
jpg3.Save("e:\\test3.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
}
Thanks in advance.
[EDIT]
User Error from a followup post:
While it's true I do have a 4608x3456 size image of the very picture I
am trying to load, I selected the wrong directory in my OpenFileDialog
and was actually selected a, you guessed it, 1613 x 1210 version of
this image. The code WAS loading the full thing, the silly operator
(me) was gumming it up.
Before I post, I'll try the full-size image ... yeah, it works fine.
Can you show your program code?
I downloaded 5169x3423 size sample image.
Load this image using program and when i restored it, original and new image are same.
I load image file to byte array and save it to Bitmap.
private Image LoadImage()
{
OpenFileDialog openFile = new OpenFileDialog();
openFile.ShowDialog();
byte[] byteImage = File.ReadAllBytes(openFile.FileName);
Image myImage;
using (var ms = new MemoryStream(byteImage))
{
myImage = Image.FromStream(ms);
}
return myImage;
}
private void SaveImage(Image myImage)
{
Bitmap bmp = new Bitmap(myImage);
// Temp save location
bmp.Save("c:\\test\\myImage.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
}

Is there a workaround for overlaying transparent images from resources?

Right now I have a form with a PictureBox on the form. I'm using two partially transparent images and trying to put one on top of the other.
sideMenuWide = rounded rectangle with transparent background (.png) [Bottom image]
labelPointer = triangle with transparent background (.png) [Top image]
Here is my approach:
// METHOD #1 //
Image img1 = Image.FromFile(#"C:\sideMenuWide.png");
Image img2 = Image.FromFile(#"C:\labelPointer.png");
picBox.Image = CombineImages(img1, img2);
// METHOD #2 //
Image imgA = RBS.Properties.Resources.sideMenuWide;
Image imgB = RBS.Properties.Resources.labelPointer;
picBox.Image = CombineImages(imgA, imgB);
And the CombineImage function: (I did not write this function, only modified)
public static Bitmap CombineImages(Image imgA, Image imgB)
{
//a holder for the result (By default, use the first image as the main size)
Bitmap result = new Bitmap(imgA.Size.Width, imgA.Size.Height);
//use a graphics object to draw the resized image into the bitmap
using (Graphics graphics = Graphics.FromImage(result))
{
//set the resize quality modes to high quality
graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
//draw the images into the target bitmap
graphics.DrawImage(imgA, 0, 0, imgA.Width, imgA.Height);
graphics.DrawImage(imgB, 100, 70, imgB.Width, imgB.Height);
}
return result;
}
Method #1 DOES work how I want it to, displays imgB perfectly on top of imgA.
Method #2 however shows imgA just fine but imgB is really faint.
Any ideas on how to overcome this? I would like to be able to do this using Resources instead of having to pull from a file.
If the files work when loaded, but the resources don't, then it sounds like the resx build process or the ResourceManager is doing something undesirable. I'd try embedding the files and reading them directly from a stream rather than relying on the ResourceManager to do it for you.
In your Solution Explorer, Add Existing File to add the file to your project. Get properties on the added file and set it to Embedded Resource=. (Don't add it to a resx file)
In your code, you can now get a stream containing the file's data:
Stream instream = Assembly.GetExecutingAssembly().
GetManifestResourceStream("RBS.labelPointer.png"));
(Hint: The compiler generates an obtuse name for the embedded resource, so after adding the files you can add temporary code to call Assembly.GetExecutingAssembly().GetManifestResourceNames() to get a list of them all and find the file you're interested in)
Load your bitmap/image from the stream:
Image img2 = new Bitmap(inStream);

How to define Image interpolation quality on windows 8 Application?

I'm making an windows 8 application.
I've a ScrollViewer with an Image inside.
The source image is really big, and the rendering with the Image is really bad (because the Image is really smaller than the source image, so the scaling make the result ugly).
Here is how I set the source image:
var baseUri = new Uri("ms-appx:///");
var bitmapImage = new BitmapImage(new Uri(baseUri, CurrentLocalization.MapPath));
MapImage.Source = bitmapImage;
My question is : how can I set the interpolation quality of the Image to have a better rendering? I don't find any ScalingMode option or InterpolationQuality...
You would need to use DirectX or SharpDX to achieve such results.

Categories