【问题标题】: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); 

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

【问题讨论】:

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

标签: c# winforms bitmap save


【解决方案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());
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-16
          • 2017-05-25
          • 2015-03-04
          • 1970-01-01
          • 2017-04-14
          • 2014-02-08
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多