GDI + LockBits使用不同的32bpp格式产生不同的步幅 [英] GDI+ LockBits producing different strides with different 32bpp formats

查看:112
本文介绍了GDI + LockBits使用不同的32bpp格式产生不同的步幅的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写代码以将图像数据从OpenGL检索到GDI +位图。在这样做时我遇到了一些奇怪的事情。



给出以下定义:





I am writing code to retrieve image data from OpenGL into a GDI+ Bitmap. While doing so I ran into something odd.

Given the following definitions:


Gdiplus::BitmapData  bmData;
Gdiplus::Rect        gRect(0, 0, 1225, 753);







以下调用在bmData中返回一个4900的步幅:






The following call returns a stride of 4900 in bmData:

LockBits(&gRect,                      // Portion of bitmap to lock
         Gdiplus::ImageLockModeWrite, // We wish to write to the bitmap
         PixelFormat32bppRGB,         // Pixel format we want
         &bmData);                    // The locked bits



以下call在bmData中返回4904的步幅:




The following call returns a stride of 4904 in bmData:

LockBits(&gRect,                       // Portion of bitmap to lock
         Gdiplus::ImageLockModeWrite,  // We wish to write to the bitmap
         PixelFormat32bppPARGB,        // Pixel format we want
         &bmData);                     // The locked bits







只有像素格式发生了变化,在这两种情况下,像素格式都是32位,但步幅大于第二种情况所需的步幅。此外,使用PixelFormat32bppARGB与第一个版本的工作方式类似(步幅为4900)。



我不确定数据是否与步幅匹配,或者步幅是否正确计算。有谁知道?




Only the pixel format has changed, and in both cases the pixel format is 32-bit, but the stride is bigger than it needs to be for the second scenario. Also, using PixelFormat32bppARGB works similarly to the first version (stride is 4900).

I'm not sure if the data matches the stride, or if the stride is incorrectly calculated. Does anyone know?

推荐答案

我认为线索是4900不能被8整除但是4904是。我怀疑原因是GDI +在使用PixelFormat32bppPARGB时,正在选择一种表示 - 包括步幅 - 更接近于一些较低级别的API或操作所期望的表现,从而以牺牲一些(微不足道的)空间为代价提供更高的效率。



例如,也许它使用SIMD指令进行alpha的预乘或其他一些与alpha相关的计算,并希望以四字形存储/获取内容而不是双字,而不处理每个扫描线末端的奇数边界条件。在另一个系统上,硬件可能更喜欢扫描线是16字节的倍数......



这就是你发现的原因你应该总是依赖给定的步幅值而不是你自己计算的值。
I think the clue is that 4900 is not divisible by 8 but 4904 is. I suspect that the reason is that GDI+, when using PixelFormat32bppPARGB, is chosing a representation - including stride - that is closer to that expected by some lower level API or manipulation, giving better efficiency overall at the expense of some (trivial) amount of space.

For example, perhaps it is using SIMD instructions to do the premultiplication of alpha, or some other alpha-related calculation, and wants to store/fetch things in quadwords rather than doubleword while not dealing with odd boundary conditions at the end of each scanline. On another system the hardware might prefer scanlines to be a multiple of 16 bytes...

This is the reason (as you discovered) you should always rely on the given values of stride and not what you calculate yourself.


这篇关于GDI + LockBits使用不同的32bpp格式产生不同的步幅的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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