c# image GDI+发生一般性错误 & c# wpf use winform‘s Image

4 篇文章 0 订阅

winform’s image通过MemoryStream保存进sql server的image字段后,再通过取出通过MemoryStream转化为Image,Image.Save()时报“GDI+发生一般性错误”,苦思良久,发现,在MemoryStream转化为Image时把Image存放到ImageList的Images中,然后再保存时不会出错,但imagelist最大只是255*255,后百度,google了N久,终于,在miscosoft找到了官方的解决办法:Bitmap对象或一个图像对象从一个文件构造时,该文件仍保留锁定于对象的生存期,因此,无法更改图像并将其保存会它。

替代方法:创建非索引映像和创建索引映像

创建非索引映像:

即使原始映像被索引格式中该方法要求新图像位于每像素, 此变通方法使用 Graphics.DrawImage() 方法来将映像复制到新 位图 对象:
1.    构造从流、 从内存, 或从文件原始 位图 。
2.    创建新 位图 的相同大小, 带有是超过 8 位 - - 像素 (BPP) 每像素格式。
3.    使用 Graphics.FromImage() 方法以获取有关二 位图 Graphics 对象。
4.    用于 Graphics.DrawImage() 绘制首 位图 到二 位图 。
5.    用于 Graphics.Dispose() 处置是 图形 。
6.    用于 Bitmap.Dispose() 是首 位图 处置。

创建索引映像

此解决办法在索引格式创建一个 Bitmap 对象:
1.    构造从流、 从内存, 或从文件原始 位图 。
2.    创建新 位图 具有相同的大小和像素格式作为首 位图 。
3.    使用 Bitmap.LockBits() 方法来锁定整个图像对于两 Bitmap 对象以其本机像素格式。
4.    使用 Marshal.Copy 函数或其他内存复制函数来从首 位图 复制到二 位图 图像位。
5.    使用 Bitmap.UnlockBits() 方法可以解锁两 Bitmap 对象。
6.    用于 Bitmap.Dispose() 是首 位图 处置。


以上都是理论上的,我也似懂非懂,具体解决例子如下:

 private byte[] ImageConventToBytes(Image img)//image to byte[]
        {
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            Bitmap bmp = new Bitmap(img);//克隆Bitmap对象
            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            byte[] bytes = new byte[ms.Length];
            ms.Seek(0, SeekOrigin.Begin);
            ms.Read(bytes, 0, Convert.ToInt32(ms.Length));
            ms.Close();
            bmp.Dispose();
            return bytes;
        }

        //private Image BytesConventToImage(byte[] bytes)//byte[] to image
        //{
        //    if (bytes.Length==0)
        //    {
        //        return null;
        //    }
        //    MemoryStream ms = new MemoryStream(bytes,0,bytes.Length);
        //    Bitmap oBitmap = new Bitmap(ms);
        //    ms.Close();
        //    return oBitmap;
        //}

 private void cSave_Click(object sender, EventArgs e)//image save to jpg file
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Title = "保存图片";
            sfd.Filter = "(*.jpg) |*.jpg";
            sfd.ShowDialog();
            if (sfd.FileName.ToString() != "")
            {
                Bitmap bmp = new Bitmap(ximage);
                bmp.Save(sfd.FileName);
                bmp.Dispose();
            }
        }

至于为啥ImageList可以正确保存,是因为ImageList给重新生一个固定大小的Image对象,和克隆道理相同

二、 wpf 使用winform中的image

首先wpf的控件的backGround是Bursh类型的,我们可以付给他一个ImageBursh对象ImageBursh有一个ImageSource属性;

ImageSource——————System.Window.Media

             |___BitmapSource

                           |___BitmapImage

                           |___BitmapFrame中有一个Create(System.IO.Stream stream)方法

到这里,都应该知道怎么转换了:

 public BitmapFrame ConvertImage(System.Drawing.Image image)
        {
            try
            {
                using (MemoryStream drawingStream = new MemoryStream())
                {
                    System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(image);
                    bmp.Save(drawingStream, System.Drawing.Imaging.ImageFormat.Jpeg);
                    drawingStream.Seek(0, SeekOrigin.Begin);
                    BitmapDecoder encoder = new JpegBitmapDecoder(drawingStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);//解码
                    bmp.Dispose();
                    //return System.Windows.Media.Imaging.BitmapFrame.Create(drawingStream);//具体原因未知,这样转换的图片,wpf中无法显示,至今还不知原因,有知道的朋友,望告知,万分感谢!
                    return encoder.Frames[0];
                }
            }
            catch (System.Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
                return null;
            }
        }




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值