如何使用 JpegBitmapEncoder 保存图像

Posted

技术标签:

【中文标题】如何使用 JpegBitmapEncoder 保存图像【英文标题】:How to save image using JpegBitmapEncoder 【发布时间】:2013-07-09 13:28:03 【问题描述】:

根据图像编码示例here,我应该可以使用JpegBitmapEncoder 对图像进行编码以保存为jpeg 文件,但出现此编译错误:

错误 CS1503:参数 1:无法从“System.Windows.Controls.Image”转换为“System.Uri”

我看不到从 Image 中获取 System.Uri 的方法(Image 中的属性或方法)。 我错过了什么?

Image xaml 代码是

<Image Name="ColorImage"/>

SaveImage C# 是

...
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);
    

下面的代码(主要取自 kinect-sdk)以 30 Fps 将 640 x 480 RBG 流式传输到 WriteableBitmap(kinect ColorImageFormat 是 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);

【问题讨论】:

看到这个JpegBitmapEncoder @Dumitru Chirutac:已经做到了。 JpegBitmapEncoder 链接在原帖中。 【参考方案1】:
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);
    

【讨论】:

【参考方案2】:

出现问题是因为您将Image 传递给BitmapFrame.CreateImage在 Windows 窗体中更为常见。一个简单的方法是先创建一个MemoryStream 然后传递:

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

加法(见 cmets 中的对话):

您可以尝试在 writeableBitmap 对象上使用CopyPixels 方法并将像素复制到一个字节数组,然后将其加载到MemoryStream,然后使用JpegBitmapEncoder 将其写入Jpeg 文件。但这只是猜测。

这也可以:

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

您只需从 Image 控件中提取 WriteableBitmap

【讨论】:

似乎没有Save 的定义或Image 的方法。编译器投诉是: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 我弄错了。我以为你在谈论'System.Drawing.Image` 如何设置图像以及从哪里获取图像? 由于答案很长,我修改了原始帖子以显示图像的设置方式 +1 提示我需要查看图像的设置方式。添加了工作代码作为答案。几天后无法将其设置为已接受。【参考方案3】:

试试:BitmapFrame.Create(image.Source)

【讨论】:

我认为这只会对从存储中读取的图像有帮助,而对动态创建的图像没有帮助。他还可以将路径传递给图像;-) @jlew:首先尝试BitmapFrame.Create(image.Source)。它会产生相同的编译器错误。

以上是关于如何使用 JpegBitmapEncoder 保存图像的主要内容,如果未能解决你的问题,请参考以下文章

如何使用laravel保存所有行数据每个行名或相等

Android登录后的用户数据如何保存,Android如何保存数据

如何在 NodeJS 中保存和显示使用 Multer 包保存的图片?

如何使用保存文件对话框保存文件

如何使用 JFileChooser 保存文件?

如何使用 JFileChooser 保存 file.txt?