【C#图像处理】关于水平镜像问题。菜鸟求助!

lin1232147 2013-03-09 06:24:30
先上代码,在选择窗体里,如果选择水平镜像,点击确定后就进行水平镜像处理
if (curBitmap != null)
{
//一个选择是否用水平镜像的窗体
mirror mirForm = new mirror();

if (mirForm.ShowDialog() == DialogResult.OK)
{
Rectangle rect = new Rectangle(0, 0, curBitmap.Width, curBitmap.Height);
System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat);
IntPtr ptr = bmpData.Scan0;
int bytes = curBitmap.Width * curBitmap.Height*3;
byte[] grayValues = new byte[bytes];
System.Runtime.InteropServices.Marshal.Copy(ptr, grayValues, 0, bytes);

int halfWidth = curBitmap.Width / 2;
int halfHeight = curBitmap.Height / 2;

byte temp;
//以上是获取图像,然后接着用内存法处理了

//主要的水平镜像处理就是在这里面了
if (mirForm.GetMirror)
{
for (int i = 0; i < curBitmap.Height; i++)
{
//这里减3是因为我下面K还多出2个
for (int j = 0; j <=halfWidth*3-2; j=j+3)
{
for (int k = 0; k < 3; k++)
{

temp = grayValues[i * curBitmap.Width * 3 + j + k];
grayValues[i * curBitmap.Width * 3 + j + k] =
grayValues[i * curBitmap.Width * 3 + (curBitmap.Width - (j / 3 + 1)) * 3 + k];

grayValues[i * curBitmap.Width * 3 + (curBitmap.Width - (j / 3 + 1)) * 3 + k] = temp;
}
}
}


}



实际上编译时候,没有出过,但是效果确十分的夸张,连纯色的图进行这段代码,都会出现其他颜色。
先说说我对水平镜像的粗浅看法,希望有人指正,首先对面处理图像,一个像素点,需要3个数值去储存。
水平镜像的原理就是 x'=width-x
y=y
但是比如第一个像素点,转移到最后一个像素点,要把数组里面存的值前3个都拿最后并且按顺序。这里我是用(j / 3 + 1)(j为X坐标)来判断现在这个点是第几个点,所以x'=width-x=width-(j/3+1).
其中还让k从0到2,能够让同一个像素点里的三个数值,按顺便转移。


但是代码实现在我想要的功能,希望能够有人可以指导下我 十分感谢
...全文
633 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Trent1985 2013-03-15
  • 打赏
  • 举报
回复
引用 18 楼 lin1232147 的回复:
引用 17 楼 Trent1985 的回复:引用 楼主 lin1232147 的回复: 先上代码,在选择窗体里,如果选择水平镜像,点击确定后就进行水平镜像处理 if (curBitmap != null) { //一个选择是否用水平镜像的窗体 mirror mirForm ……
呵呵,给你发的是我自己的博客
lin1232147 2013-03-14
  • 打赏
  • 举报
回复
引用 17 楼 Trent1985 的回复:
引用 楼主 lin1232147 的回复: 先上代码,在选择窗体里,如果选择水平镜像,点击确定后就进行水平镜像处理 if (curBitmap != null) { //一个选择是否用水平镜像的窗体 mirror mirForm = new mirror(); ……
太有用了 太感谢了 跟发现了个宝藏一样。 好多关于图像的讲解
Trent1985 2013-03-13
  • 打赏
  • 举报
回复
引用 楼主 lin1232147 的回复:
先上代码,在选择窗体里,如果选择水平镜像,点击确定后就进行水平镜像处理 if (curBitmap != null) { //一个选择是否用水平镜像的窗体 mirror mirForm = new mirror(); ……
这个太简单了,给你代码,你直接用吧,速度绝对没问题!方法1http://dongtingyueh.blog.163.com/blog/static/461945320117992835689/ 方法2:http://dongtingyueh.blog.163.com/blog/static/461945320126169522784/ http://dongtingyueh.blog.163.com/blog/static/461945320126178162240/
cst09046 2013-03-13
  • 打赏
  • 举报
回复
帮忙顶一下 论坛上关于图像处理的帖子不多
lin1232147 2013-03-12
  • 打赏
  • 举报
回复
引用 8 楼 sbicfwxf9 的回复:
可能是我没看明白。。。图片直接就能翻转和旋转了,RotateFlipType有好多枚举的;比如旋转90度: Image i = Image.FromStream(ms); i.RotateFlip(RotateFlipType.Rotate90FlipXY);
又多学个。谢谢·我试了你这个呀。我直接打开个图片存到curBitmap 然后curBitmap.RotateFlip(RotateFlipType.Rotate90FlipXY);就能翻转。。 我用 public byte[] imageToByteArray(System.Drawing.Image imageIn) { System.IO.MemoryStream ms = new System.IO.MemoryStream(); imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif); return ms.ToArray(); } private void button8_Click(object sender, EventArgs e) { System.IO.MemoryStream ms = new System.IO.MemoryStream (imageToByteArray(curBitmap)); Image i = Image.FromStream(ms); i.RotateFlip(RotateFlipType.Rotate90FlipXY); Invalidate(); } 这样反而达不到效果 真是无奈。。。实在太菜了我,多指教
dylike 2013-03-12
  • 打赏
  • 举报
回复
System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); 既然是3位3位下去,那么这里最后一个参数要用24位RGB。
dylike 2013-03-12
  • 打赏
  • 举报
回复
Bitmap B = new Bitmap(Label1.Image); B.RotateFlip(RotateFlipType.RotateNoneFlipX); Label2.Image = B;
lin1232147 2013-03-12
  • 打赏
  • 举报
回复
引用 12 楼 dylike 的回复:
System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); 既然是3位3位下去,那么这里最后一个参数要用24位RGB。
3位3位去计算真心很麻烦啊。有没有办法1个像素只用1个空间储和计算啊 那样就方便多了
lin1232147 2013-03-12
  • 打赏
  • 举报
回复
引用 12 楼 dylike 的回复:
System.Drawing.Imaging.BitmapData bmpData = curBitmap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, curBitmap.PixelFormat); 既然是3位3位下去,那么这里最后一个参数要用24位RGB。
嗯 这次我打开的图是Format24bppRgb像素格式的。但是还是失败了。我觉得应该是我代码问题``或许我一开始就不应该用这么复杂的方法··
lin1232147 2013-03-12
  • 打赏
  • 举报
回复
引用 7 楼 Mackz 的回复:
你去查了没有,这个像素格式就是一个像素占多少空间,根据这个来进行你的内存处理,尤其是行对齐,否则当然就乱掉了。
我终于明白你说的是什么意思了。各种图片的像素格式还不一样。。PixelFormat 枚举也是有好多种。这次我用 PixelFormat.ToString()找打了张Format24bppRgb像素格式的图片进行我之前所写代码的水平镜像·· 很模糊。而且右部分颜色还有点乱 ..
lin1232147 2013-03-12
  • 打赏
  • 举报
回复
我又去查了下 直接就有Image.RotateFlip 方法,所以 那样做成功了 Image.FromStream (Stream) 方法从指定的数据流创建 Image。但是不明白为什么失败了
sbicfwxf9 2013-03-11
  • 打赏
  • 举报
回复
可能是我没看明白。。。图片直接就能翻转和旋转了,RotateFlipType有好多枚举的;比如旋转90度: Image i = Image.FromStream(ms); i.RotateFlip(RotateFlipType.Rotate90FlipXY);
菜牛 2013-03-10
  • 打赏
  • 举报
回复
你去查了没有,这个像素格式就是一个像素占多少空间,根据这个来进行你的内存处理,尤其是行对齐,否则当然就乱掉了。
lin1232147 2013-03-10
  • 打赏
  • 举报
回复
引用 4 楼 Mackz 的回复:
这有啥好教的,你用的LockBits函数最后一个参数不就是像素格式么,查MSDN中的 PixelFormat 就是了。
比较菜。PixelFormat属性只是让我们知道像素格式。你的意思也是说让我用GetPixel和SetPixel这2个方法来处理么。不好意思 比较菜。
lin1232147 2013-03-09
  • 打赏
  • 举报
回复
引用 1 楼 gxingmin 的回复:
楼主参考下这个
谢谢哈 对我解决和实现镜像有很大的帮助啊。这个是用提取像素法,那我用内存法能解决么。始终我也研究了好一伙了。真心也想知道我的问题是出在哪里了
菜牛 2013-03-09
  • 打赏
  • 举报
回复
这有啥好教的,你用的LockBits函数最后一个参数不就是像素格式么,查MSDN中的 PixelFormat 就是了。
lin1232147 2013-03-09
  • 打赏
  • 举报
回复
但是我现在看的书是教我3个字节表示一个像素。。。如果用32位INT也可以表示 那就方便多了。。但是我不会啊。。求教,
引用 2 楼 Mackz 的回复:
图像有很多颜色格式,可不都是3字节一个像素!
菜牛 2013-03-09
  • 打赏
  • 举报
回复
图像有很多颜色格式,可不都是3字节一个像素!
gxingmin 2013-03-09
  • 打赏
  • 举报
回复

110,538

社区成员

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

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

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