WPF程序:图像的ARGB数字矩阵输出。发现某些像素点结果不正确。谁帮忙看看哪里出了问题?

bdssckwpf 2012-03-19 02:36:36
代码如下,运行即可。



<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="700" Width="700" Background="Green"
>
<Grid>
<TextBlock Name="TB"></TextBlock>
</Grid>
</Window>





using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Test
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();


BitmapImage bi = new BitmapImage(new Uri("D:\\03.png"));
byte[] b = new byte[4 * bi.PixelWidth * bi.PixelHeight];
Int32Rect rect = new Int32Rect(0, 0, bi.PixelWidth, bi.PixelHeight);
bi.CopyPixels(rect, b, bi.PixelWidth * 4, 0);


for (int i = 1; i <= bi.PixelHeight; i++)
{
for (int j = 1; j <= bi.PixelWidth; j++)
{
int z = 4 * (i - 1) * bi.PixelWidth + 4 * (j - 1);

this.TB.Text += (b[z + 0] + "、" + b[z + 1] + "、" + b[z + 2] + "、" + b[z + 3] + "、 ");
}
this.TB.Text += "\r\n";
}


}



}
}


...全文
221 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
bdssckwpf 2012-03-21
  • 打赏
  • 举报
回复
解决方法已经找到:
使用如下方法,载入图片即可:

BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
bi.UriSource = new Uri("D:\\03.png");
bi.EndInit();
startstartsvip 2012-03-20
  • 打赏
  • 举报
回复
察看了一下

是因为存成 bytes

ARGB,在 字节 里 是 little-endian 就是说 是 BGRA

this.TB.Text += (b[z + 0] + "、" + b[z + 1] + "、" + b[z + 2] + "、" + b[z + 3] + "、 ");

B G R A


用 BinaryReader sr= new BinaryReader(ms);
sr.ReadInt32() 就可以得到正确值

你可以用下面的方法验证:


targe.SetPixel(j, i, Color.FromArgb(sr.ReadInt32()));
Color c= targe.GetPixel(j, i);

bdssckwpf 2012-03-20
  • 打赏
  • 举报
回复
我的图片应该是没有问题的吧,都是用photoshop制作的。

你试试用photoshop制作一幅3*3的png图片,然后,给这9个点,分别给予不通的颜色,再用我这个程序调试来看看?

就简单的9个点,就会发现,读取进来的ARGB值,其中怎么也有两三个点,是有偏差的。

[Quote=引用 6 楼 startstartsvip 的回复:]

我电脑上都是一样的
应该是你图片的问题 BitsPerPixel

C# code

BitmapImage bi = new BitmapImage(new Uri(@"C:\Users\LionHeart\Pictures\rb.png"));
byte[] b = new byte[4 * bi.PixelWidth * bi.Pixel……
[/Quote]
startstartsvip 2012-03-20
  • 打赏
  • 举报
回复
哦 原来这样啊
bdssckwpf 2012-03-20
  • 打赏
  • 举报
回复
我好像找到了原因了:


用windows画图工具制作的png图片,格式是bgr32。

用photoshopCS5制作的png图片,格式是bgra32。

而腾讯的logo图片,格式是Indexed8。

是不是因为虽然都是png图片,但色彩模型不一样,因此,读取argb值就需要用不同的方法?


[Quote=引用 11 楼 startstartsvip 的回复:]

cs4 png 画了 三条 纯 RGB 色彩带 读入没有问题,没有一点误差
[/Quote]
bdssckwpf 2012-03-20
  • 打赏
  • 举报
回复
这幅图片,是腾讯主页上的logo的地址(你可以直接去腾讯首页拿下来),如下:

http://mat1.gtimg.com/www/iskin960/qqcomlogo.png


你用这幅图片测试,试试看。在我这里测试,就有偏差。



[Quote=引用 11 楼 startstartsvip 的回复:]

cs4 png 画了 三条 纯 RGB 色彩带 读入没有问题,没有一点误差
[/Quote]
startstartsvip 2012-03-20
  • 打赏
  • 举报
回复
cs4 png 画了 三条 纯 RGB 色彩带 读入没有问题,没有一点误差

bdssckwpf 2012-03-20
  • 打赏
  • 举报
回复
argb和bgra的细节,我是知道的。

不知道你那里有没有photoshop软件,有的话,可以用photoshop建一幅3*3的图片来测试。

不要用windows自带的画图软件,因为这个软件生成的图片,经过测试,是没有问题的。

我想问题的关键点就是:图片是photoshop生成的。

至于原因,我就不知道为什么了。


[Quote=引用 8 楼 startstartsvip 的回复:]

察看了一下

是因为存成 bytes

ARGB,在 字节 里 是 little-endian 就是说 是 BGRA

this.TB.Text += (b[z + 0] + "、" + b[z + 1] + "、" + b[z + 2] + "、" + b[z + 3] + "、 ");

B ……
[/Quote]
bdssckwpf 2012-03-20
  • 打赏
  • 举报
回复
我用你的方法:SetPixel(j, i, Color.FromArgb(sr.ReadInt32()));

得到的,和我的程序得到的,是一致的结果。

例如某个像素本来是:(121,200,189,255),最后读入后,却变成了(120,201,191,255).

用SetPixel(j, i, Color.FromArgb(sr.ReadInt32()));也是一样有偏差。

我猜是因为图像是用photoshop生成的缘故,因为我用画图工具来生成图片,就没有出过问题。


[Quote=引用 8 楼 startstartsvip 的回复:]

察看了一下

是因为存成 bytes

ARGB,在 字节 里 是 little-endian 就是说 是 BGRA

this.TB.Text += (b[z + 0] + "、" + b[z + 1] + "、" + b[z + 2] + "、" + b[z + 3] + "、 ");

B ……
[/Quote]
startstartsvip 2012-03-19
  • 打赏
  • 举报
回复
我电脑上都是一样的
应该是你图片的问题 BitsPerPixel


BitmapImage bi = new BitmapImage(new Uri(@"C:\Users\LionHeart\Pictures\rb.png"));
byte[] b = new byte[4 * bi.PixelWidth * bi.PixelHeight];
Int32Rect rect = new Int32Rect(0, 0, bi.PixelWidth, bi.PixelHeight);
bi.CopyPixels(bi.SourceRect, b, bi.Format.BitsPerPixel * bi.PixelWidth/8, 0);

Bitmap targe = new Bitmap(bi.PixelWidth, bi.PixelHeight);

MemoryStream ms= new MemoryStream(b);
BinaryReader sr= new BinaryReader(ms);
for (int i = 0; i < bi.PixelHeight; i++)
{
for (int j = 0; j < bi.PixelWidth; j++)
{

targe.SetPixel(j, i, Color.FromArgb(sr.ReadInt32()));

}

}

sr.Close();
ms.Close();
pictureBox1.Image = targe;
startstartsvip 2012-03-19
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 startstartsvip 的回复:]

bi.CopyPixels(rect, b, bi.PixelWidth * 4, 0);


bi.CopyPixels(rect, b, bi.PixelWidth * bi.PixelHeight * 4, 0);


copy 错了吧
[/Quote]

不对,我说错了 那个是 stride

有人也用 bi.PixelWidth* ((bi.Format.BitsPerPixel + 7) / 8)





startstartsvip 2012-03-19
  • 打赏
  • 举报
回复
bi.CopyPixels(rect, b, bi.PixelWidth * 4, 0);


bi.CopyPixels(rect, b, bi.PixelWidth * bi.PixelHeight * 4, 0);


copy 错了吧
bdssckwpf 2012-03-19
  • 打赏
  • 举报
回复
有人能回复一下吗?
bdssckwpf 2012-03-19
  • 打赏
  • 举报
回复
求大牛一定要帮忙调调。

我要做一个小型的图片编辑的软件,因此,要精确地获取图像的像素值。

现在第一步就出现坎了:读取进来的图像的像素值,与原图像不相符。
bdssckwpf 2012-03-19
  • 打赏
  • 举报
回复
大家是否看得明白输出的结果?

大家可以用一些小图片来测试一下,输出结果就很直观了。

尽量用较小的图片:如5*5,6*6,7*7等等。

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧