Open nowheremanmail opened 8 years ago
I can't even get the SDK to load properly on my phone (I get a missing component error at runtime). Did you have to do any troubleshooting? Is it the 10/Universal version? I'd love to figure out why it's not working for everyone. Thanks!
The issue has been reported on StackOverflow Switching to CPU rendering fixes the issue. This is not a solution, but hopefully a clue for MSFT on how to fix it; We had to workaround this by loading the original twice. Obviously not ideal. Hoping for an update to sdk soon.
This affects a variety of renderers. I encountered the problem (of EXIF rotation/orientation information being partially ignored) with WriteableBitmapRenderer
and JpegRenderer
.
When doing renderer.RenderOptions = RenderOptions.Cpu
, the problem goes away. I assume that that can carry a performance penalty.
One consequence of that bug is that the aspect ratio is off. So the renderer assumes the oriented dimensions when laying out the render size. So non-square images look very off.
Is there any time frame for a bugfix release of the Lumia Imaging SDK?
BTW: Many thanks for this project, even though the 3.0 release has proven somewhat cumbersome (there is that other bug with it not working in the current Windows 10 Mobile emulators)
We struggled with this as well on Windows Phone. Only applies to images with EXIF orientation tags.
For now, we are using the following code to switch between GPU and CPU if the image contains Exif data:
using (var image = await sourceFile.OpenStreamForReadAsync())
{
bool exifRotation = false;
if (angleForRotation == 0)
{
exifRotation = false;
var exif = ExifReader.ReadJpeg(image);
switch (exif.Orientation)
{
case ExifOrientation.BottomLeft:
case ExifOrientation.BottomRight:
case ExifOrientation.TopLeft:
case ExifOrientation.TopRight:
exifRotation = true;
break;
}
}
image.Seek(0, SeekOrigin.Begin);
using (var source = new RandomAccessStreamImageSource(image.AsRandomAccessStream()))
{
using (var scale = new ScaleEffect(source, scaleFactor))
using (var rotation = scaleFactor < 1 ? new RotationEffect(scale, angleForRotation) : new RotationEffect(source, angleForRotation))
using (var renderer = new JpegRenderer(rotation) { Quality = quality })
{
var info = await source.GetInfoAsync();
renderer.RemoveExif = true;
if (exifRotation || ((MemoryManager.AppMemoryUsageLimit / 1024) / 1024) < 200)
{
renderer.RenderOptions = RenderOptions.Cpu;
}
var buffer = await renderer.RenderAsync();
using (var output = await newFile.OpenAsync(FileAccessMode.ReadWrite))
{
await output.WriteAsync(buffer);
await output.FlushAsync();
}
}
}
}
It's true, there appears to be a bug in the Lumia Imaging SDK when it comes to EXIF orientation and rendering on GPU.
That said, there is an easy workaround. When you first load an IImageProvider from an StorageFile, make a temporray bitmap and use that as a source in your other rendering operations. That way you will only take the penalty of a CPU-only render operation once, in the most limited possible scenario. All your other rendering operations will the optimally GPU accelerated.
Here is a helper method to use when using a StorageFile as a source:
public static async Task<IImageProvider> CreateImageSourceFromFile(StorageFile file)
{
using (var source = new StorageFileImageSource(file))
using (var renderer = new BitmapRenderer(source) { RenderOptions = RenderOptions.Cpu })
{
var bitmap = await renderer.RenderAsync();
return new BitmapImageSource(bitmap);
}
}
@davidbozjak - thanks for the tip. We had been doing something similar to @jamesmundy 's suggestion for months now. Your approach is definitely cleaner for us at this point. Do you know if a newer version of the SDK is coming out soon? where can I keep my ears to the ground for that?
Regards,
Eric.
Some pictures in JPG format with rotation information, are not correctly processed in QuickStart sample. Open quick start sample and select given image. You will see that image is not correctly processed.