0
votes

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.

3
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
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

3 Answers

0
votes

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.

0
votes

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();
                        }
                    }
0
votes

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();
                    }
                }
            }