0

I am having a tough time converting lumia imaging SDK 2.0 code to SDK3.0 in below specific case. I used to increase/decrease the image quality of JPG file using below code in Windows phone 8.1 RT apps:

using (StreamImageSource source = new StreamImageSource(fileStream.AsStreamForRead()))
                    {
                        IFilterEffect effect = new FilterEffect(source);
                        using (JpegRenderer renderer = new JpegRenderer(effect))
                        {
                            renderer.Quality = App.COMPRESSION_RATIO / 100.0; // higher value means better quality
                            compressedImageBytes = await renderer.RenderAsync();
                        }
                    }

Now since FilterEffect class has been replaced in SDK 3.0 with EffectList(), I changed code to

 using (BufferProviderImageSource source = new BufferProviderImageSource(fileStream.AsBufferProvider()))
                {
                    using (JpegRenderer renderer = new JpegRenderer())
                    {
                        IImageProvider2 source1 = new EffectList() { Source = source };
                        renderer.Source = source1;                    
                        renderer.Quality = App.COMPRESSION_RATIO / 100.0;
                        try
                        {
                            var img = await renderer.RenderAsync();
                        }
                        catch (Exception ex)
                        {
                            ;
                        }
                    }
                }

I am getting InvalidCastException exception. I have tried several combinations but no luck.

harshbodhi
  • 99
  • 9
  • Where are you getting the invalid cast exception? When you render, that is call renderAsync()? Or does the exception happen even before? – David Božjak Jan 08 '16 at 07:47
  • Actually I just tried rendering with an empty list and that worked without a problem. So I take that back. Perhaps it is something with your stream? If you just create a ColorImageSource as the source, will it work for you? – David Božjak Jan 08 '16 at 08:06

3 Answers3

0

I don't really know what is going on with the InvalidCastException, we can continue that discussion in the comments as it will most likely need some back-and-forth.

That said, you could continue without the effect list, and chain effects in the normal way. So to rewrite your scenario:

using (var soruce = new StreamImageSource(...))
using (var renderer = new JpegRenderer(source))
{
    renderer.Quality = App.COMPRESSION_RATIO / 100.0;
    var img = await renderer.RenderAsync();
}

If you wanted to add an effect (for example a CarttonEffect), just do:

using (var soruce = new StreamImageSource(...))
using (var caroonEffect = new CartoonEffect(source))
using (var renderer = new JpegRenderer(caroonEffect))
{
    renderer.Quality = App.COMPRESSION_RATIO / 100.0;
    var img = await renderer.RenderAsync();
}

and so on. If you had effects A, B, C and D just make a chain Source -> A -> B -> C -> D -> JpegRenderer.

David Božjak
  • 16,887
  • 18
  • 67
  • 98
  • I edited the answer and removed the bit about the empty EffectList, as that seems to work without a problem. – David Božjak Jan 08 '16 at 08:07
  • Thanks David for responding. I get this exception while calling renderAsync(). I do not want to add any effect but to reduce the quality of image which I was able to achieve by setting the Quality property. However I tried the solution you posted above(Without effect) but did not work. Getting System.Exception: The component cannot be found. (Exception from HRESULT: 0x88982F50) – harshbodhi Jan 10 '16 at 09:56
  • In case you don't want to apply any effects to the image you don't need the EffectList. As per the component cannot be found exception that looks as VS bug from a while back. Are you running visual studio 2013 Update 4? Have you considered upgrading/updating? – David Božjak Jan 10 '16 at 14:21
  • Hi David, I have posted my observation along with a code snippet. – harshbodhi Jan 10 '16 at 19:00
0

I am on VS 2015 community version. While digging around this, I got below code working which works exactly same as SDK 2.0. All I did was specified the Size of JpegRenderer. It works for all landscape images but fails to transform the portrait images to correct orientation. There is no exception but result of portrait image is widely stretched landscape image. I initialized the Size for portrait images to Size(765, 1024) but no impact.

 using (JpegRenderer renderer = new JpegRenderer(source))
                    {
                        renderer.Quality = App.COMPRESSION_RATIO / 100.0;

                        try
                        {
                            var info = await source.GetInfoAsync();
                            renderer.Size = new Size(1024, 765);
                            compressedImageBytes = await renderer.RenderAsync();

                        }
                        catch (Exception ex)
                        {
                            new MessageDialog("Error while compressing.").ShowAsync();
                        }
                    }
harshbodhi
  • 99
  • 9
  • Just to verify, can you remove the call to GetInfoAsync()? Apart from it not being needed in your snippet, it is also deprecated in Lumia Imaging SDK 3.0. So I just want to verify, can you remove it, or do you get a different exception if you don't make that call? – David Božjak Jan 11 '16 at 07:31
  • As for the stretching, what do you have set for the OutputOpetion on the JpegRenderer? Make sure you have "PreserveAspectRatio" set. If the image is still stretched it could be a bug. Could you provide the output image so I can see what kind of stretching occurs? – David Božjak Jan 11 '16 at 07:34
0

I am sorry the working code was using BufferProviderImageSource instead StreamImageSource. Below is the snippet. Few points here:

1) If I don't use Size property I get "The component cannot be found exception".

2) GetInfoAsync(): Yes it was useless for above code but I need to use it to know if image is Landscape or Portrait so that I can initialize Size property of resultant image.

3) If Size property goes beyond 1024x1024 for portrait images I get the exception "Value does not fall within the expected range"

Why lumia made this version so tricky. :(

  var stream = FileIO.ReadBufferAsync(file);

            using (var source = new BufferProviderImageSource(stream.AsBufferProvider()))
            {
                EffectList list = new EffectList() { Source = source };
                using (JpegRenderer renderer = new JpegRenderer(list))
                {
                    renderer.Quality = App.COMPRESSION_RATIO / 100.0;
                    renderer.OutputOption = OutputOption.PreserveAspectRatio;
                    try
                    {
                        var info = await source.GetInfoAsync();
                        double width = 0;
                        double height = 0;
                        if (info.ImageSize.Width > info.ImageSize.Height) //landscape
                        {
                            width = 1024;
                            height = 765;
                            if (info.ImageSize.Width < 1024)
                                width = info.ImageSize.Width;
                            if (info.ImageSize.Height < 765)
                                height = info.ImageSize.Height;
                        }
                        else //portrait..
                        {
                            width = 765;
                            height = 1024;
                            if (info.ImageSize.Width < 765)
                                width = info.ImageSize.Width;
                            if (info.ImageSize.Height < 1024)
                                height = info.ImageSize.Height;
                        }

                        renderer.Size = new Size(width, height);
                        compressedImageBytes = await renderer.RenderAsync();
                    }
                    catch (Exception ex)
                    {
                        new MessageDialog(ex.Message).ShowAsync();
                    }
                }
            }
harshbodhi
  • 99
  • 9