锁位.如何遍历像素?有文件大小限制吗? [英] Lockbits. How to iterate through pixels? Any file size limits?

查看:92
本文介绍了锁位.如何遍历像素?有文件大小限制吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是一个自学成才的初学者,我在这上面花了似乎几天的时间.当我再次陷入困境时,我以为我会问Code Project的好心人.我一直想遍历大像素(10K +像素乘以10K +像素)1bit Windows位图的像素,并决定使用Lockbits.

I''m a self taught beginner and I''ve spent what seems like days on this one. As I''m stuck again, I''d thought I''d ask the kind people here at Code Project. I have been wanting to iterate through the pixels of large (10K+ pixels by 10K+ pixels) 1bit Windows bitmaps and decided on Lockbits.

' Lock the bitmap's bits and put in array
       Dim FullRect As New Rectangle(0, 0, FWBitmap.Width, FWBitmap.Height)
       Dim bmpData As System.Drawing.Imaging.BitmapData = FWBitmap.LockBits(FullRect, _
           Drawing.Imaging.ImageLockMode.ReadWrite, FWBitmap.PixelFormat)

       ' Get the address of the first line of bitmap.
       Dim ptr As IntPtr = bmpData.Scan0

       ' Declare an array to hold the bytes of the bitmap.
       Dim bytes As Integer = (bmpData.Stride) * (FWBitmap.Height)
       Dim EachByte(bytes - 1) As Byte

       ' Copy the bitmap's RGB values into the array.
       System.Runtime.InteropServices.Marshal.Copy(ptr, EachByte, 0, bytes)



然后我通过以下命令遍历字节并在其中移动:



Then I was stepping through and within the bytes with:

 CurrentByte = Math.Truncate((Point.Y * bmpData.Stride) + ((Point.X) / 8))

CurrentByteBit = 8 * ((Point.Y * bmpData.Stride) + ((Point.X) / 8) - CurrentByte) + 1



数组看起来还可以(尽管Visual Studio很大时通常会停止运行).但是,我从数组中移出的像素值似乎不像原始位图.我怀疑我在这里缺少明显的东西!?



The array appears okay (although Visual Studio often ceases up when it''s very big). However, the pixel values I''m getting out of the array don''t appear to resemble the original bitmap. I suspect I am missing something obvious here !?

推荐答案

您的注释是指位图为RGB.那让我担心你走错了路.

让我们回顾一下1位图像的工作原理:
图像中的每个像素都是黑色或白色.
我们可以在1个字节中存储8个像素.
不压缩时,步幅=宽度/8(给定或采用),总字节数=步幅*高度.
根据文件类型以及是否在PC,Mac或其他设备上创建的文件,字节中的第一个像素可以= 1或128,第二个2或64,依此类推.这称为字节顺序.

假设我们有一排交替黑白像素的像素,例如
X X X X X X X X X X X X X X X X X X X X X X ...
因此每个字节为0x01 + 0x04 + 0x10 + 0x40 = 0x55
还在我这儿? (另外,看看这些数字看起来有多好?这就是程序员使用十六进制的原因.)

现在让我们来看一下您的代码.

Your comment refers to the bitmap being RGB. That concerns me that you''re on the wrong track.

Let''s review how 1-bit images work:
Each pixel in the image is either black or white.
We can store 8 pixels in 1 byte.
Without compression, stride = width / 8 (give or take), and totalbytes = stride * height.
Depending on the file type, and whether it was created on a PC, Mac or other, the first pixel in a byte may = 1 or 128, the second 2 or 64, etc. This is called endianess.

Let''s say we had a row of pixels that alternated black and white pixels like
X X X X X X X X X X X X X X X X X X X X X X ...
So each byte would be 0x01 + 0x04 + 0x10 + 0x40 = 0x55
Still with me? (also, see how nice those numbers look? That''s why programmers use hex.)

Now let''s look at your code.

CurrentByte = Math.Truncate((Point.Y * bmpData.Stride) + ((Point.X) / 8))



假设我们对[0,0]处的像素感兴趣.
Point.Y == 0
bmpData.Stride ==比方说1000.
Point.X == 0
CurrentByte = Math.Truncate(0 * 1000) + (0 / 8)
CurrentByte == Math.Truncate(0)
CurrentByte == 0

看到问题了吗?您从未参考过实际的像素数据,而只是参考坐标.
要获取实际的像素数据,您需要
CurrentPixel = FWBitmap.GetPixel(x,y)

现在已经很清楚了,不要那样做.您仍然需要将CurrentPixel拆分为多个位,您的应用程序将非常缓慢.

现在,请原谅我的无知,但我不知道VB.NET是否像C#一样具有unsafe代码和指针.我想是这样.您需要查一下.任何曾经尝试编写处理大图像的成像应用程序的人最终都意识到,您需要使用指针来使其以任何可接受的性能运行.

希望这对您有帮助!



Let''s say we''re interested in the pixel at [0,0].
Point.Y == 0
bmpData.Stride == let''s say 1000.
Point.X == 0
CurrentByte = Math.Truncate(0 * 1000) + (0 / 8)
CurrentByte == Math.Truncate(0)
CurrentByte == 0

Do you see a problem? You never referred to the actual pixel data, just coordinates.
To get actual pixel data you''d need
CurrentPixel = FWBitmap.GetPixel(x,y)

Now that that''s clear, DON''T DO THAT. You''ll still need to split CurrentPixel out into its bits and your application will be VERY SLOW.

Now, excuse my ignorance but I don''t know if VB.NET has unsafecode and pointers like C# does. I assume so. You''ll need to look that up. Anyone who has ever attempted to write an imaging application that handles large images has eventually realized that you need to use pointers to make it work with any kind of acceptable performance.

Hope this helps!


是一篇有关Lockbits的出色文章,在遇到问题时对我有帮助我正在做一些1bpp图像处理.

让我震惊的一件事是,当您在调试器中查看阵列时,映像倒置了!
This is an excellent article on Lockbits and helped me when I was doing some 1bpp image processing.

One thing that tripped me up is that when you look at the array in the debugger the image is upside down!


这篇关于锁位.如何遍历像素?有文件大小限制吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆