位图跨度和4个字节的关系?(Bitmap Stride And 4 bytes Relation?)
这句话是什么意思:
Stride属性以字节为单位保存一行的宽度。 然而,行的大小可能不是像素大小的精确倍数,因为为了提高效率,系统可确保将数据打包到从四字节边界开始的行中,并填充为四个字节的倍数。
Whats does this sentence mean:
The Stride property, holds the width of one row in bytes. The size of a row however may not be an exact multiple of the pixel size because for efficiency, the system ensures that the data is packed into rows that begin on a four byte boundary and are padded out to a multiple of four bytes.
原文:https://stackoverflow.com/questions/5735997
更新时间:2019-06-05 19:58
最满意答案
步幅是填充的。 这意味着它四舍五入到4的最接近倍数(假设8位灰度,或每像素8位):
Width | stride
--------------
1 | 4
2 | 4
3 | 4
4 | 4
5 | 8
6 | 8
7 | 8
8 | 8
9 | 12
10 | 12
11 | 12
12 | 12
等等
在C#中,你可以像这样实现它:
static int PaddedRowWidth(int bitsPerPixel, int w, int padToNBytes)
{
if (padToNBytes == 0)
throw new ArgumentOutOfRangeException("padToNBytes", "pad value must be greater than 0.");
int padBits = 8* padToNBytes;
return ((w * bitsPerPixel + (padBits-1)) / padBits) * padToNBytes;
}
static int RowStride(int bitsPerPixel, int width) { return PaddedRowWidth(bitsPerPixel, width, 4); }
Stride is padded. That means that it gets rounded up to the nearest multiple of 4. (assuming 8 bit gray, or 8 bits per pixel):
Width | stride
--------------
1 | 4
2 | 4
3 | 4
4 | 4
5 | 8
6 | 8
7 | 8
8 | 8
9 | 12
10 | 12
11 | 12
12 | 12
etc.
In C#, you might implement this like this:
static int PaddedRowWidth(int bitsPerPixel, int w, int padToNBytes)
{
if (padToNBytes == 0)
throw new ArgumentOutOfRangeException("padToNBytes", "pad value must be greater than 0.");
int padBits = 8* padToNBytes;
return ((w * bitsPerPixel + (padBits-1)) / padBits) * padToNBytes;
}
static int RowStride(int bitsPerPixel, int width) { return PaddedRowWidth(bitsPerPixel, width, 4); }
相关问答
步幅是填充的。 这意味着它四舍五入到4的最接近倍数(假设8位灰度,或每像素8位): Width | stride
--------------
1 | 4
2 | 4
3 | 4
4 | 4
5 | 8
6 | 8
7 | 8
8 | 8
9 | 12
10 | 12
11 | 12
12 | 12
等等 在C#中,你可以像这样实现它: static int PaddedRowWidth(int bitsP
...
我只注意到编辑,它有一个特殊的答案。 如果你需要在同一个数据上做很多不同的位置,那么你现在的计划是好的。 如果您只需要128B内存中的一个位(特别是最高位位置),则可以使用_mm256_movemask_ps从每个32b元素中获取高位。 然后在GP寄存器中组合四个8位掩码。 一个好的编译器应该优化它以: vmovdqu ymm0, [buf + 0]
; to select a different bit:
; vpslld ymm0, ymm0, count ; count can b
...
如果要将更多信息传递给顶点着色器而不仅仅是顶点的位置,可以使用所谓的interwinded数组。 例如: struct Information {
GLfloat position[3];
GLfloat color[3];
GLfloat texture[2];
};
因此,这种结构的一种可能的实例化是: struct Information vertices[] = {
// Positions // Colors //
...
尝试: while ((string = br.readLine()) != null)
{
bytesRead += (string.getBytes().length);
}
try: while ((string = br.readLine()) != null)
{
bytesRead += (string.getBytes().length);
}
这似乎在这里工作: private Bitmap ByteToImage(int w, int h, byte[] pixels)
{
var bmp = new Bitmap(w, h, PixelFormat.Format16bppRgb565);
byte bpp = 2;
var BoundsRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits
...
我已经解决了关于法线的问题。 代码是: v_pointer = ctypes.c_void_p(0) # or None
n_pointer = ctypes.c_void_p(12)
c_pointer = ctypes.c_void_p(24)
v_stride = 36
n_stride = 36
c_stride = 36
但是我仍然有颜色问题,因为模型并不丰富多彩? :)非常感谢任何想法。 I have solved the pro
...
一次复制1行,计算行的起始指针为((byte*)scan0 + (y * stride)) 。 代码对于正向或负向步幅都是相同的。 Copy 1 row at a time, calculating the starting pointer for a row as ((byte*)scan0 + (y * stride)). The code will be identical for either positive or negative stride.
使用填充是由于各种(旧的和当前的)内存布局优化。 使图像像素行具有4/8/16字节的整数倍的长度(以字节为单位)可以显着简化和优化许多基于图像的操作。 原因是这些尺寸允许在CPU寄存器中进行正确的存储和并行像素处理,例如使用SSE / MMX,而不需要混合来自两个连续行的像素。 如果没有填充,则必须插入额外的代码来处理部分WORD / DWORD像素数据,因为内存中的两个连续像素可能指向一行右侧的一个像素和下一行左侧的像素。 如果您的图像是8位深度的单通道图像,即灰度在[0,255]范围内,则步幅
...
我写了一个简短的示例,它将填充数组的每一行以使其适应所需的格式。 它将创建一个2x2检查板位图。 byte[] bytes =
{
255, 255, 255,
0, 0, 0,
0, 0, 0,
255, 255, 255,
};
var columns = 2;
var rows = 2;
var stride = columns*4;
var newbytes = PadLines(bytes, rows, co
...
因此,看起来这就是使用金属缓冲区的Just The Way It Is™:您必须填充着色器结构以匹配app结构的步幅。 我不认为Metal shader运行时从缓冲区加载stride字节并sizeof(MyShaderStruct)它们的第一个sizeof(MyShaderStruct)会很困难。 或者在附加管道状态时自动加载结构。 但这些便利可能具有效率影响。 这是我的Swift / Shader结构现在的样子供参考: 金属: struct Particle
{
float3 positi
...