为什么一定要“大步"?在 System.Drawing.Bitmap 构造函数中是 4 的倍数? [英] Why must "stride" in the System.Drawing.Bitmap constructor be a multiple of 4?

查看:17
本文介绍了为什么一定要“大步"?在 System.Drawing.Bitmap 构造函数中是 4 的倍数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个应用程序,它要求我采用专有位图格式(MVTec Halcon HImage)并将其转换为 C# 中的 System.Drawing.Bitmap.

I am writing an application that requires me to take a proprietary bitmap format (an MVTec Halcon HImage) and convert it into a System.Drawing.Bitmap in C#.

提供给我的唯一专有函数可以帮助我做到这一点,除了使用获取指针"函数之外,我还需要写入文件.

The only proprietary functions given to me to help me do this involve me writing to file, except for the use of a "get pointer" function.

这个函数很棒,它给了我一个指向像素数据、宽度、高度和图像类型的指针.

This function is great, it gives me a pointer to the pixel data, the width, the height, and the type of the image.

我的问题是,当我使用构造函数创建 System.Drawing.Bitmap 时:

My issue is that when I create my System.Drawing.Bitmap using the constructor:

new System.Drawing.Bitmap(width, height, stride, format, scan)

我需要指定一个 4 的倍数的步幅".这可能是一个问题,因为我不确定我的函数将使用什么大小的位图.假设我最终得到一个 111x111 像素的位图,除了在我的图像中添加一个假列或减去 3 列之外,我没有办法运行这个函数.

I need to specify a "stride" that is a multiple of 4. This may be a problem as I am unsure what size bitmap my function will be hit with. Supposing I end up with a bitmap that is 111x111 pixels, I have no way to run this function other than adding a bogus column to my image or subtracting 3 columns.

有什么办法可以绕过这个限制吗?

Is there a way I can sneak around this limitation?

推荐答案

这可以追溯到早期的 CPU 设计.处理位图位的最快方法是一次读取 32 位,从扫描线的开头开始.当扫描线的第一个字节在 32 位地址边界上对齐时,效果最佳.换句话说,地址是 4 的倍数.在早期的 CPU 上,第一个字节未对齐会花费额外的 CPU 周期来从 RAM 读取两个 32 位字并混洗字节以创建 32 位值.确保每条扫描线都从一个对齐的地址开始(如果步幅是 4 的倍数,则自动)可以避免这种情况.

This goes back to early CPU designs. The fastest way to crunch through the bits of the bitmap is by reading them 32-bits at a time, starting at the start of a scan line. That works best when the first byte of the scan line is aligned on a 32-bit address boundary. In other words, an address that's a multiple of 4. On early CPUs, having that first byte mis-aligned would cost extra CPU cycles to read two 32-bit words from RAM and shuffle the bytes to create the 32-bit value. Ensuring each scan line starts at an aligned address (automatic if the stride is a multiple of 4) avoids that.

这在现代 CPU 上不再是一个真正的问题,现在与缓存线边界对齐更为重要.然而,由于应用兼容的原因,步幅的 4 倍数要求仍然存在.

This isn't a real concern anymore on modern CPUs, now alignment to the cache line boundary is much more important. Nevertheless, the multiple of 4 requirement for stride stuck around for appcompat reasons.

顺便说一句,您可以使用以下格式和宽度轻松计算步幅:

Btw, you can easily calculate the stride from the format and width with this:

        int bitsPerPixel = ((int)format & 0xff00) >> 8;
        int bytesPerPixel = (bitsPerPixel + 7) / 8;
        int stride = 4 * ((width * bytesPerPixel + 3) / 4);

这篇关于为什么一定要“大步"?在 System.Drawing.Bitmap 构造函数中是 4 的倍数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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