2

According to the image encoding example here I should be able to use JpegBitmapEncoder to encode an image for saving as a jpeg file but get this compile error:

error CS1503: Argument 1: cannot convert from 'System.Windows.Controls.Image' to 'System.Uri'

I don't see a way (property or method in Image) to get System.Uri from Image. What am I missing?

The Image xaml code is

<Image Name="ColorImage"/>

The SaveImage C# is

...
SaveImage(ColorImage, path);
...
private void SaveImage(Image image, string path)
{
    var jpegEncoder = new JpegBitmapEncoder();
    jpegEncoder.Frames.Add(BitmapFrame.Create(image));
    using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        jpegEncoder.Save(fs);
    }
}

The code below (taken mostly from the kinect-sdk) streams 640 x 480 RBG to a WriteableBitmap at 30 Fps (the kinect ColorImageFormat is RgbResolution640x480Fps30).

using (var colorImageFrame = allFramesReadyEventArgs.OpenColorImageFrame())
{
    if (colorImageFrame == null) return;
    var haveNewFormat = currentColorImageFormat != colorImageFrame.Format;
    if (haveNewFormat)
    {
        currentColorImageFormat = colorImageFrame.Format;
        colorImageData = new byte[colorImageFrame.PixelDataLength];
        colorImageWritableBitmap = new WriteableBitmap(
            colorImageFrame.Width, 
            colorImageFrame.Height, 96, 96, PixelFormats.Bgr32, null);
        ColorImage.Source = colorImageWritableBitmap;
    }
    // Make a copy of the color frame for displaying.
    colorImageFrame.CopyPixelDataTo(colorImageData);
    colorImageWritableBitmap.WritePixels(
        new Int32Rect(0, 0, colorImageFrame.Width, colorImageFrame.Height),
        colorImageData,
        colorImageFrame.Width*Bgr32BytesPerPixel,
        0);
}
jacknad
  • 13,483
  • 40
  • 124
  • 194

3 Answers3

3
private void SaveImage(string path)
{
    var jpegEncoder = new JpegBitmapEncoder();
    jpegEncoder.Frames.Add(BitmapFrame.Create(colorImageWritableBitmap));
    using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
    {
        jpegEncoder.Save(fs);
    }
}
jacknad
  • 13,483
  • 40
  • 124
  • 194
2

The problem occurs, because you pass an Image to BitmapFrame.Create. Imageis more common in Windows Forms. A simple approach would be to create a MemoryStream first and the pass this:

private void SaveImage(Image image, string path)
    {
        MemoryStream ms = new MemoryStream();
        image.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);
        var jpegEncoder = new JpegBitmapEncoder();
        jpegEncoder.Frames.Add(BitmapFrame.Create(ms));
        using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
        {
            jpegEncoder.Save(fs);
        }
    }

Addition (see conversation in comments):

you could try to use the CopyPixels method on the writeableBitmap object and copy the pixels to a byte array which you load to a MemoryStream and the write it to a Jpeg File withe the JpegBitmapEncoder. But it's just a guess.

This could work, too:

     private void SaveImage (WriteableBitmap img, string path)
     {
         FileStream stream = new FileStream(path, FileMode.Create);
         JpegBitmapEncoder encoder = new JpegBitmapEncoder();
         encoder.Frames.Add(BitmapFrame.Create(img));
         encoder.Save(stream);
         stream.Close();
     }

You will just have to extract the WriteableBitmap from your Image control

Romano Zumbé
  • 7,893
  • 4
  • 33
  • 55
  • There does not seem to be a `Save` definition or method for `Image`. The compiler complaint is: `error CS1061: 'System.Windows.Controls.Image' does not contain a definition for 'Save' and no extension method 'Save' accepting a first argument of type 'System.Windows.Controls.Image' could be found` – jacknad Jul 09 '13 at 15:12
  • I got that wrong. I thaught you were talking about 'System.Drawing.Image` – Romano Zumbé Jul 09 '13 at 15:43
  • How do you set the Image and where do you get it from? – Romano Zumbé Jul 09 '13 at 15:46
  • Since it was a long answer I modified the original post to show how the image is set – jacknad Jul 09 '13 at 16:49
  • +1 for hint that I need to look at how the image is set. Added working code as answer. Can't set it as accepted for a couple of days. – jacknad Jul 09 '13 at 17:54
0

Try: BitmapFrame.Create(image.Source)

jlew
  • 10,491
  • 1
  • 35
  • 58
  • I think this will only help with images read from storage and not for images that were created dynamically. He could also joust pass the path to the image ;-) – Romano Zumbé Jul 09 '13 at 13:45
  • @jlew: Tried `BitmapFrame.Create(image.Source)` first. It produces the same compiler error. – jacknad Jul 09 '13 at 15:13