1

I have a Silverlight Out-of-browser application and I want to save pictures on a specified directory. In the application, I have the picture loaded in a BitmapImage and I wish to save it on the HardDrive (in jpg if possible). My code :

private void SaveImageToImagePath(BitmapImage image)
{
    string path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Images");
    if (!Directory.Exists(path))
    {
        Directory.CreateDirectory(path);
    }

    Save(image, new FileStream(Path.Combine(path, String.Format("{0}.jpg", _imageName)), FileMode.OpenOrCreate));
}

private void Save(BitmapSource bitmapSource, FileStream stream)
{
    var writeableBitmap = new WriteableBitmap(bitmapSource);

    for (int i = 0; i < writeableBitmap.Pixels.Length; i++)
    {
        int pixel = writeableBitmap.Pixels[i];

        byte[] bytes = BitConverter.GetBytes(pixel);
        Array.Reverse(bytes);

        stream.Write(bytes, 0, bytes.Length);
    }
} 

I have also tried with this method to pass from BitmapImage to ByteArray:

private byte[] ToByteArray(WriteableBitmap bmp)
{
    // Init buffer 
    int w = bmp.PixelWidth;
    int h = bmp.PixelHeight;
    int[] p = bmp.Pixels;
    int len = p.Length;
    byte[] result = new byte[4 * w * h];

    // Copy pixels to buffer 
    for (int i = 0, j = 0; i < len; i++, j += 4)
    {
        int color = p[i];
        result[j + 0] = (byte)(color >> 24); // A 
        result[j + 1] = (byte)(color >> 16); // R 
        result[j + 2] = (byte)(color >> 8);  // G 
        result[j + 3] = (byte)(color);       // B 
    }

    return result;
} 

The problem is that the file I get is unreadable (corrupted) and when I try to read it from the application, I got a Catastrophic Failure. I also noticed that the file generated by the application is four time heavier than the original...

Thank you for your help !

Philippe

Sources :

Can I get a byte[] from a BitmapImage in Silverlight?

Silverlight: image to byte[]

Community
  • 1
  • 1
Philippe
  • 986
  • 1
  • 6
  • 17
  • Yeah i got the same problem on two different computer. Even more, I am working with high volume of pictures (>1000) and they are all corrupted... – Philippe Nov 21 '11 at 04:49
  • there is more than pixels in the image file... see http://stackoverflow.com/questions/4161359/save-bitmapimage-to-file for code that should work. – Yaur Nov 21 '11 at 04:59
  • 1
    As good as this solution should be in WPF, it doesn't work in Silverlight because JpegBitmapEncoder is not avalaible... – Philippe Nov 21 '11 at 05:09
  • +1 for providing your code. Makes it much easier to spot issues. – iCollect.it Ltd Nov 24 '11 at 11:21

1 Answers1

1

A JPG file is a complex set of compressed data, optimized to give the best compression for photo-realistic images. It does this by identifying patterns of colour in square areas throughout the image and removing redundancy.

It is not just a set of RGB values, but you are simply writing the pixel byte values out to a file. What you are writing is basically a RAW image file. If you load a photo tool that reads RAW image files (and specify the size) you will be able to view it but that is not the problem you are trying to solve.

Your best bet in Silverlight is to save them to PNG files using a PNGEncoder or maybe .Net Image Tools, else you will need to find another custom library that can duplicate JPG compression/saving.

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
  • I already tried to encode the image in jpeg with ImageTools and I got 1 Ko image... The fact is I don't really need a JPEG image or any image I can read with an image viewer. I only need to be able to read it from my silverlight application. Don't you think it should work if I just write all the bytes in a raw file and then read them back and put them in a new BitmapImage (BitmapImage.SetSource). I am also afraid of possible Insufficient memory ... – Philippe Nov 21 '11 at 19:20
  • Reading and writing raw bytes will work if you also write out the other information you need to reconstruct it (image dimensions etc), however that is a really inefficient way to store them. The memory requirements are the same once it is loaded. – iCollect.it Ltd Nov 22 '11 at 08:35
  • I finally got it with the jpegencoder in the .Net Image tools by resolving the 1ko image issue... Thanks for your advices ! – Philippe Nov 23 '11 at 05:11