Search code examples
c#compact-frameworkwindows-ce

Check if device has support saving in JPEG and PNG format


I need to save image to PNG format. Unfortunately on old devices (with WinCE 5.0) image can only saved in BMP format:

 try
 {
   destinationBmp.Save(fileName+".png", ImageFormat.Png);
 }
 catch (NotSupportedException)
 {
   // No PNG & JPG support on Windows CE 5.0 devices
   //
   destinationBmp.Save(fileName+".bmp", ImageFormat.Bmp);
}
finally
{
    destinationBmp.Dispose();
}

Is there possible to check image format support without handling NotSupportedException?


Solution

  • Windows CE 5.0 is capable of supporting JPEG and PNG encoding, but it depends on how the vendor of your device has configured the operating system image. If they have not included the codecs then it will not work. If you are the vendor who creates the windows image, you can add these to your device using platform builder.

    The method that you are using is probably the simplest way to decide if it is capable of saving PNG or JPG images. However, it is not, in the general sense, correct to assume that if it doesn't support PNG that it also does not support JPG (looking at your try/catch code you would need a try/catch for each format).

    If you have knowledge about all the possible devices your code runs on, then using @HansPassant 's suggestion of checking Environment.OSVersion may be reasonable for you to decide that it is one of the Win CE 5.0 devices you are aware of that doesn't support JPG and PNG. Otherwise, it is not correct to assume Windows CE 5.0 is not capable.

    If you want an exact way of determining which codecs are installed you may find that solution by interacting with the Imaging COM Interface (Reference Here). Specifically, it appears you need to call IImagingFactory.GetInstalledEncoders.

    My suggestion would probably be to keep it simple and create a test image and attempt to save it in each format to a MemoryStream once and catch NotSupportedExceptions to determine the capability of your device. That way you do not need to create a file.

    Note:

    The COM import would look something like this but you'll need to fill in the place holder for the GetInstallEncoders method you wanted with the correct arguments (Sorry I wasn't using this). Then call Activator.CreateInstance(...) you'll need to be familiar with interacting with COM Interfaces in .NET.

        [ComImport, Guid("327ABDA7-072B-11D3-9D7B-0000F81EF32E"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        [ComVisible(true)]
        public interface IImagingFactory
        {
            uint CreateImageFromStream();       // This is a place holder, note the lack of arguments
            uint CreateImageFromFile(string filename, out IImage image);
            // We need the MarshalAs attribute here to keep COM interop from sending the buffer down as a Safe Array.
            uint CreateImageFromBuffer([MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint size, BufferDisposalFlag disposalFlag, out IImage image);
            uint CreateNewBitmap(uint width, uint height, PixelFormatID pixelFormat, out IBitmapImage bitmap);
            uint CreateBitmapFromImage(IImage image, uint width, uint height, PixelFormatID pixelFormat, InterpolationHint hints, out IBitmapImage bitmap);
            uint CreateBitmapFromBuffer();      // This is a place holder, note the lack of arguments
            uint CreateImageDecoder();          // This is a place holder, note the lack of arguments
            uint CreateImageEncoderToStream();  // This is a place holder, note the lack of arguments
            uint CreateImageEncoderToFile();    // This is a place holder, note the lack of arguments
            uint GetInstalledDecoders();        // This is a place holder, note the lack of arguments
            uint GetInstalledEncoders();        // This is a place holder, note the lack of arguments
            uint InstallImageCodec();           // This is a place holder, note the lack of arguments
            uint UninstallImageCodec();         // This is a place holder, note the lack of arguments
        }