博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF BitmapSourceToArray and ArrayToBitmapSource
阅读量:7158 次
发布时间:2019-06-29

本文共 8157 字,大约阅读时间需要 27 分钟。

   WPF时至今日,也是N多开发人员的必修课了,但是也许很多人和我一样遇到了某种需求,需要把图片存进数据库,在必要的时候再查出来予以显示,问题就出来了,WPF相对Winform改动的东西还是比较多的,例如没有了Bitmap,改成了BitmapImage,原来Winform里的Image也没有了,在WPF里变成了一个控件。可是数据库只能存放byte[],而我们在WPF里操作最直接的是BitmapSource,这可如何是好,必须进行相互间的转化了。

  百度谷歌搜狗了N久无果,虽然找到一些,但是经测试全都不行,无一例外的达不到效果,无奈只好拍脑袋自己搞。。

  经过一系列蛋疼的测试,感觉BitmapSource下的CopyPixels方法还靠点谱,然后就先搞了个,但是怎么测试这个方法给我们的byte[]正确呢,还要在转回去才能看到效果,我一向信奉事实说话,然后就上msdn各种翻,最后锁定BitmapSource下的Create方法,于是开始测试,测试程序很简单,界面上两个Image控件,左边一个,右边一个,中间一个Button,click里面就一句话

1 image2.Source = ArrayToBitmapSource(BitmapSourceToArray((BitmapSource)image1.Source));

当我写完这句的时候就开始浑身蛋疼。。Create需要的参数我没办法提供,这可怎么搞,接着拍脑袋,由于ArrayToBitmapSource这个方法因为需求只能获得一个byte[],只好在这个byte[]上动脑筋了,既然他是数组,是用来存放数据的玩意儿,那么我可不可以通过他把Create需要的东西传进去呢,于是看了下Create的参数类型,除了一个PixelFormat枚举之外全是int,我靠,爽歪歪吧。。

 

然后就开始敲:

1 public byte[] BitmapSourceToArray(BitmapSource bitmapSource)  2         {
3 int height = bitmapSource.PixelHeight; 4 int width = bitmapSource.PixelWidth; 5 int stride = width * ((bitmapSource.Format.BitsPerPixel + 7) / 8); 6 byte[] bits = new byte[height * stride + 3]; 7 bitmapSource.CopyPixels(bits, stride, 0); 8 bits[bits.Length - 3] = (byte)(width); 9 bits[bits.Length - 2] = (byte)(width); 10 bits[bits.Length - 1] = (byte)(width); 11 return bits; 12 }
public BitmapSource ArrayToBitmapSource(byte[] imageBytes)         {
PixelFormat pf = PixelFormats.Bgra32; int width = (imageBytes[imageBytes.Length -3]); int height = (imageBytes[imageBytes.Length - 2]); int rawStride = (imageBytes[imageBytes.Length - 1]); List
tempList = imageBytes.ToList(); tempList.RemoveRange(imageBytes.Length - 3, 3); imageBytes = tempList.ToArray(); BitmapSource bmpImage = BitmapSource.Create(width, height, 96, 96, pf, null, imageBytes, rawStride); return bmpImage; }

看上去很美,或许会有人觉得这样就可以了,可是当我写下(byte)进行强制转换的时候,心里就感觉有问题了,果然,编译运行报错了,很自然的我断点看了下width值在强转过程中是否丢失精度,一看发现确实如此,怎么办呢,一个是int,一个是byte,突然我就想起来当初写象棋的时候用一个int存放四个byte来表示一种走法,这里可不可以用呢,int是32位的,byte是8位的,由于都是正数,无视符号位,嘿嘿,这不刚好四个byte可以表示一个int吗,于是激动的拿着键盘开敲:

1  public byte[] BitmapSourceToArray(BitmapSource bitmapSource)  2         {
3 int height = bitmapSource.PixelHeight; 4 int width = bitmapSource.PixelWidth; 5 int stride = width * ((bitmapSource.Format.BitsPerPixel + 7) / 8); 6 byte[] bits = new byte[height * stride + 12]; 7 bitmapSource.CopyPixels(bits, stride, 0); 8 bits[bits.Length - 12] = (byte)(width >> 24); 9 //16711680就是二进制的: 10 // 0000 0000 1111 1111 0000 0000 0000 000011 11 bits[bits.Length - 11] = (byte)(width&16711680); 12 //65280就是二进制的: 13 // 0000 0000 0000 0000 1111 1111 0000 000014 14 bits[bits.Length - 10] = (byte)(width &65280); 15 //255对应的二进制就是: 16 // 0000 0000 0000 0000 0000 0000 1111 111117 17 bits[bits.Length - 9] = (byte)(width & 255); 18 bits[bits.Length - 8] = (byte)(height >> 24); 19 bits[bits.Length - 7] = (byte)(height&16711680); 20 bits[bits.Length - 6] = (byte)(height&65280); 21 bits[bits.Length - 5] = (byte)(height & 255); 22 bits[bits.Length - 4] = (byte)(stride >> 24); 23 bits[bits.Length - 3] = (byte)(stride &16711680); 24 bits[bits.Length - 2] = (byte)(stride &65280); 25 bits[bits.Length - 1] = (byte)(stride & 255); 26 return bits; 27 }

 

1 public BitmapSource ArrayToBitmapSource(byte[] imageBytes)  2         {
3 PixelFormat pf = PixelFormats.Bgra32; 4 int width = (imageBytes[imageBytes.Length - 12] << 24) 5 + (imageBytes[imageBytes.Length - 11] << 16) 6 + (imageBytes[imageBytes.Length - 10] << 8) 7 + (imageBytes[imageBytes.Length - 9]); 8 9 int height = (imageBytes[imageBytes.Length - 8] << 24) 10 + (imageBytes[imageBytes.Length - 7] << 16) 11 + (imageBytes[imageBytes.Length - 6] << 8) 12 + (imageBytes[imageBytes.Length - 5]); 13 14 int rawStride = (imageBytes[imageBytes.Length - 4] << 24) 15 + (imageBytes[imageBytes.Length - 3] << 16) 16 + (imageBytes[imageBytes.Length - 2] << 8) 17 + (imageBytes[imageBytes.Length - 1]); 18 19 20 List
tempList = imageBytes.ToList(); 21 tempList.RemoveRange(imageBytes.Length - 12, 12); 22 imageBytes = tempList.ToArray(); 23 BitmapSource bmpImage = BitmapSource.Create(width, height, 24 96, 96, pf, null, 25 imageBytes, rawStride); 26 return bmpImage; 27 }

然后那个激动啊,点了下按钮开始测试,卡了半天愣是没看到那个美女图片出来,好歹给个反应啊,不一会儿vs2010表态了:
{System.ArgumentException: 值不在预期的范围内。 ---> System.ArgumentException: 值不在预期的范围内。

顿时我就内牛满面,太不给面子了吧,这什么个情况嘛 T_T

 

然后我就想,换个写法试试,于是擦了把泪拿起键盘开敲:

public byte[] BitmapSourceToArray(BitmapSource bitmapSource)         {
int height = bitmapSource.PixelHeight; int width = bitmapSource.PixelWidth; int stride = width * ((bitmapSource.Format.BitsPerPixel + 7) / 8); byte[] bits = new byte[height * stride + 12]; bitmapSource.CopyPixels(bits, stride, 0); bits[bits.Length - 12] = (byte)(width >> 24); bits[bits.Length - 11] = (byte)((width << 8) >> 24); bits[bits.Length - 10] = (byte)((width << 16) >> 24); bits[bits.Length - 9] = (byte)(width & 255); bits[bits.Length - 8] = (byte)(height >> 24); bits[bits.Length - 7] = (byte)((height << 8) >> 24); bits[bits.Length - 6] = (byte)((height << 16) >> 24); bits[bits.Length - 5] = (byte)(height & 255); bits[bits.Length - 4] = (byte)(stride >> 24); bits[bits.Length - 3] = (byte)((stride << 8) >> 24); bits[bits.Length - 2] = (byte)((stride << 16) >> 24); bits[bits.Length - 1] = (byte)(stride & 255); return bits; }

 

1 public BitmapSource ArrayToBitmapSource(byte[] imageBytes)  2         {
3 PixelFormat pf = PixelFormats.Bgra32; 4 int width = (imageBytes[imageBytes.Length - 12] << 24) 5 + (imageBytes[imageBytes.Length - 11] << 16) 6 + (imageBytes[imageBytes.Length - 10] << 8) 7 + (imageBytes[imageBytes.Length - 9]); 8 9 int height = (imageBytes[imageBytes.Length - 8] << 24) 10 + (imageBytes[imageBytes.Length - 7] << 16) 11 + (imageBytes[imageBytes.Length - 6] << 8) 12 + (imageBytes[imageBytes.Length - 5]); 13 14 int rawStride = (imageBytes[imageBytes.Length - 4] << 24) 15 + (imageBytes[imageBytes.Length - 3] << 16) 16 + (imageBytes[imageBytes.Length - 2] << 8) 17 + (imageBytes[imageBytes.Length - 1]); 18 19 20 List
tempList = imageBytes.ToList(); 21 tempList.RemoveRange(imageBytes.Length - 12, 12); 22 imageBytes = tempList.ToArray(); 23 BitmapSource bmpImage = BitmapSource.Create(width, height, 24 96, 96, pf, null, 25 imageBytes, rawStride); 26 return bmpImage; 27 }

点击按钮开始测试,神了,久违的美女图片显示出来了,顿时感动的想要以身相许了。。(可惜没人要 = =)

感动了一会儿我就开始郁闷了,为什么我进行与运算来取值就取的不对呢,百思不得其解,还请高人指点。。

感谢下被我折腾了这么久的那位美女童鞋的照片,当然也要感谢她本人了。。

自始至终Button里的代码都是这句:

1  private void button1_Click(object sender, RoutedEventArgs e) 2         { 3             image2.Source = ArrayToBitmapSource(BitmapSourceToArray((BitmapSource)image1.Source)); 4         }

 

到此,大功告成了,其中还有很多可优化的地方,还请高人指点,还有那个最重要的问题:

为什么我进行与运算来取值就取的不对呢,百思不得其解

希望知道原因的大侠给小弟点指点,感激不尽,临表涕零啊。。

(话说能上首页吗,搞到晚上一点多。。希望能和大家分享,更希望能有高人看到给我指点下那个问题。。)

转载于:https://www.cnblogs.com/lipf/archive/2012/02/23/2364208.html

你可能感兴趣的文章
全网备份
查看>>
Java 重大升级马上来了:JDK 11 新特性了解一下
查看>>
字符串转换成NSDate类型的 为nil解决方法
查看>>
Ubuntu git 与 gitlab 关联
查看>>
C++ 上溢和下溢(overflow underflow)
查看>>
Maven_运行时环境
查看>>
动态规划——Best Time to Buy and Sell Stock III
查看>>
grid布局
查看>>
常用的mysql操作
查看>>
转: spring静态注入
查看>>
C#反射机制
查看>>
类的私有成员方法、final成员字段、永恒类(String)
查看>>
Objective-C 学习记录4
查看>>
Martin Fowler关于IOC和DI的文章(中文版)
查看>>
安装jumpserver
查看>>
[leetcode.com]算法题目 - Sqrt(x)
查看>>
Python自带的hmac模块
查看>>
2102 石子归并 2
查看>>
poj 3352
查看>>
ubuntu卸载vmware player
查看>>