如何保存位图

Posted

技术标签:

【中文标题】如何保存位图【英文标题】:How to save a bitmap 【发布时间】:2016-09-13 15:52:05 【问题描述】:

在 WPF 中,我有一个来自处理我的网络摄像头的库的位图

Bitmap bmp = webCameraControl.GetCurrentImage();

现在我必须保存它但是 bmp.Save("C:/img.jpg");失败 所以我尝试了

bmp.Save("C:/img.jpg", ImageFormat.Jpeg);

但它没有工作并得到了

“通用 GDI+ 错误”。

谢谢

---添加---

所以如果我放

bmp.Save("C:\\img.jpg", ImageFormat.Jpeg);
bmp.Save(@"C:\img.jpg", ImageFormat.Jpeg); 

我得到错误。 但是如果我把

bmp.Save("img.jpg", ImageFormat.Jpeg); 

这行得通!我看不懂!=?!?

【问题讨论】:

有人在这里找到了解决方案:***.com/questions/15571022/… 值得一试。 当然,现在您保存到本地目录,相对于项目文件夹(或 exe)。您的程序很可能没有对根目录的写入权限。选择类似 C:\temp\... 【参考方案1】:

“通用 GDI+ 错误”。如果您要存储它的目录的路径不存在,大多数情况下会发生。

检查路径是否存在 检查路径是否有效

bmp.Save("C:\\Test\\img.jpg", ImageFormat.Jpeg); 确保使用\\@"C:\Test\img.jpg"

如果这一切都不起作用,您可能无权保存到C:\\

【讨论】:

是的,我用两个 \\ 写它,但文本框正在思考,因为 sql 注入【参考方案2】:

您是否尝试过将图像保存到其他位置? 我猜这个目录是受windows本身保护的。

解决方案:

在解决方案资源管理器中右键单击您的项目文件,选择添加,然后选择新建项目。在那里你可以找到应用程序清单文件。

它创建名为 app.manifest 的文件。打开它并找到标签 requestedPrivileges。 (如下图)

<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
    <!-- ##GERMAN TEXT##

    <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
    <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
    <requestedExecutionLevel  level="highestAvailable" uiAccess="false" /> ##GERMAN TEXT##
    -->
    <requestedExecutionLevel level="asInvoker" uiAccess="false" />
  </requestedPrivileges>

您感兴趣的线路是这一行:

<requestedExecutionLevel level="asInvoker" uiAccess="false" />

它说你作为调用者(“asInvoker”)执行它。 将其更改为“requireAdministrator”并以管理员身份重新启动 VisualStudio。

这应该成功了:)

编辑

我忘了提到我用这两行代码试过了。 当我以管理员身份运行它时,它对我有用。

        Bitmap bmp = new Bitmap(12,12);
        bmp.Save("C:/img.jpg", ImageFormat.Jpeg);

【讨论】:

【参考方案3】:

我猜你遇到的问题是你的保存路径中的“/”。您可以使用以下两种方式之一编写它:

bmp.Save("C:\\img.jpg", ImageFormat.Jpeg); //two backslashes escapes to a single backslash

bmp.Save(@"C:\img.jpg", ImageFormat.Jpeg); //adding @ escapes the backslash automatically

编辑 I found this over at Super User,您可以使用C:\ 来解决这个问题。使用路径"%HomeDrive%\\img.jpg",它是C 驱动器的内置路径快捷方式。我不知道这在 C# 中的可靠性如何,但在我上次尝试时它工作正常,当我现在在文件资源管理器中测试时它工作正常。

不过,对该目录的写入权限似乎是您最可能遇到的问题。如果是这样的话,我不知道该怎么办。

【讨论】:

【参考方案4】:

这是我的做法:

public static void RotateAndSaveImage(string path, WriteableBitmap bitmap, double angle)

    try
    
        if (bitmap != null)
        
            var tb = new TransformedBitmap((bitmap), new RotateTransform(angle));
            var src = tb as BitmapSource;

            using (FileStream stream = new FileStream(path, FileMode.Create))
            
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(src));
                encoder.Save(stream);
            
        
     catch 

【讨论】:

哦,到底发生了什么?我会立即 【参考方案5】:

你也可以这样做:

private void RotateAndSaveImage(int pageNumber, double angleOfRotation)
  
     EnsureNotDisposed();

     // create the encoder
     BitmapEncoder encoder = BitmapEncoder.Create(Decoder.CodecInfo.ContainerFormat);

     // copy the destination frames
     foreach (BitmapFrame frame in Decoder.Frames)
        encoder.Frames.Add(frame);

     BitmapFrame oldFrame = encoder.Frames[pageNumber - 1];

     // Create the TransformedBitmap to use as the Image source.
     TransformedBitmap tb = new TransformedBitmap();

     // Properties must be set between BeginInit and EndInit calls.
     tb.BeginInit();

     tb.Source = new CachedBitmap(oldFrame, BitmapCreateOptions.None, BitmapCacheOption.None);

     RotateTransform transform = new RotateTransform(angleOfRotation);
     tb.Transform = transform;

     tb.EndInit();

     encoder.Frames.RemoveAt(pageNumber - 1);
     encoder.Frames.Insert(pageNumber - 1, BitmapFrame.Create(tb));
     // save encoder
     Save(encoder)
  
  
  /// <summary>
  /// Saves the contents of a bitmap encoder to <see cref="Stream"/>.
  /// </summary>
  /// <param name="encoder">
  /// The encoder from which to obtain the data to save.
  /// </param>
  private void Save(BitmapEncoder encoder)
  
     // save to a temporary stream
     string tempFileName = Path.GetTempFileName();

     try
     
        using (FileStream temporaryStream = new FileStream(tempFileName, FileMode.OpenOrCreate))
        
           if (encoder.Frames.Count > 0)
              encoder.Save(temporaryStream);

           // write back out to permanent stream
           if (Stream.CanWrite && Stream.CanSeek)
              CopyStream(temporaryStream, Stream);
           else
              throw new UnauthorizedAccessException();
        
     
     finally
     
        // Delete the temporary file
        File.Delete(tempFileName);
     
  

【讨论】:

【参考方案6】:

您可以将位图保存到流中并将其转换为 base64String。一旦你有了它,你想用它做什么。

bitmap.Save(stream, ImageFormat.png);
return Convert.ToBase64String(stream.ToArray());

【讨论】:

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

将位图保存到位置

如何将位图保存在从 Internet 下载的内部存储中

如何从 ARGB_8888 位图绘制位图

如何使用Pillow从图像创建位图而不保存图像?

如何使用matlab将256灰度位图图像保存为24位灰度图像?

如何将位图文件附加到电子邮件