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.
Related
I am having some trouble with Image control in WPF.
I have one jpg file, which loads with wrong rotation and even i rotate this picture in windows (right click and rotate left/right) there is no change in application.
Seems that there are some EXIF metadata in the image, which gets rotated together with a wrong image.
I'm reading the image from www so I do not have local file (and I don't want to have it). Here's how I'm converting byte[] to BitmapImage:
public static BitmapImage BitmapImageFromByteArray(Byte[] bytes)
{
MemoryStream stream = new MemoryStream(bytes);
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = stream;
image.EndInit();
stream.Close();
stream.Dispose();
return image;
}
So there are 2 ways of handling that:
Set Image control to ignore EXIF metadata
Remove EXIF metadata from BitmapImage
Can you help me with handling any of these?
Check out the code sample on the following link.
Remove Exif data from image files with C# and WPF libraries: http://www.techmikael.com/2009/07/remove-exif-data-from-image-files-with.html
Another option may be to use a RotateTransform to rotate the Image element:
How to do rotation around control's center in XAML
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.
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);
}
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.
I'm working on a program where I need to place an image on top of another image. What happening though is when I place the picture on top of the background it gets changed to a different resolution and I'm not sure why. I've tried messing around with the bit depth and DPI, but neither of them made any difference. My original image is 574x574, but when it places it on the picture, it becomes 768x768. Here is the code I'm using. Any help is appreciated.
Image imgBackground = Image.FromFile(r_strApplicationStartupPath + "\\images\\Backing.png");
Image imgPicture1 = Image.FromFile(r_strApplicationStartupPath + "\\images\\Picure1.png");
Image TempImg = Image.FromFile(r_strApplicationStartupPath + "\\images\\Backing.png");
Graphics grfx = Graphics.FromImage(TempImg);
Bitmap bmpFinal = new Bitmap(1296, 1944, PixelFormat.Format32bppArgb);
grfx = Graphics.FromImage(bmpFinal);
grfx.DrawImage(imgBackground, 0, 0);
grfx.DrawImage(imgPicture1, 659, 1282);
bmpFinal.Save(r_strApplicationStartupPath + "\\images\\" + r_strName + " Composite " + r_intCounter.ToString() + ".png", ImageFormat.Png);
When you call Graphics.DrawImage without specifying the destination rectangle, it assumes that you want to preserve the original physical size of the image (i.e. inches rather than pixels), so the image is resized based upon the DPI of the source image and the destination image.
If you want to ensure that the image gets drawn at the original pixel size without adjusting the DPIs then you just need to provide the entire destination rectangle.
grfx.DrawImage(imgPicture1, dstRect, srcRect, GraphicsUnit.Pixel);