【问题标题】:Unpacking (r,g,b) raw pixel buffer in C在 C 中解包 (r,g,b) 原始像素缓冲区
【发布时间】:2013-04-11 17:33:43
【问题描述】:

目前正在尝试将 C 用于以前在 python (pypy) 中完成的工作。我想我会尝试用 C 语言编写它(以获得最佳速度),并使用 ctypes 进行通信。

现在我要做的是从位图(bmp 文件)中获取像素缓冲区,将其发送到 C 函数,该函数将原始缓冲区转换为 R、G、B 值的平面数组并返回它到蟒蛇。但是在尝试将“缓冲区”转换为 R、G、B 值时,我遇到了困难。 在 python 中,我会简单地使用“struct”模块:B,G,R = struct.unpack('<BBB', buffer[i:i+3])

我应该如何在 C 中做同样的事情?

Python:

from bmplib import Bitmap
import ctypes
lib = ctypes.CDLL('_bitmap.dll') 

bmp = Bitmap()
bmp.open('4x4.bmp')
buf = bmp._rawAsArray() #Returns a array.array() of char (raw pixel-data)

addr, count = buf.buffer_info()
lib.getData.argtypes = []

arr = ctypes.cast(addr, ctypes.POINTER(ctypes.c_char))
lib.getData(arr, count) #Does not return anything yet..

C 尝试转换像素失败:

#include <stdio.h>

void getData(char *, const int);
void getData(char * array, const int length) {
  int i = 0;
  while(i < length) {
    /* ----- Clearly wrong as i got some HUGE number----- */
    printf("%d, ", ((int *) array)[i]   << 8); //B 
    printf("%d, ", ((int *) array)[i+1] << 8); //G
    printf("%d\n", ((int *) array)[i+2] << 8); //R
    i += 3;
  }
  //return total;
}

【问题讨论】:

  • char * array 中有什么?每个字节一个样本?
  • 即使它被淘汰了:@leonbloy,这是正确的。

标签: python c arrays bitmap ctypes


【解决方案1】:

不清楚您在char * array 中收到的图像格式。假设每个数组元素有一个字节,则无需进行任何移位:

 while(i < length) {
    printf("%d, ", (unsigned int)array[i++]); //B 
    printf("%d, ", (unsigned int)array[i++]); //G
    printf("%d\n", (unsigned int)array[i++]); //R
  }

但是请记住,BMP 图像的每一行都可以有一些填充,因此只有当 array 对应于单行并且length 不包含填充时,这才有效。

【讨论】:

  • 是的,我知道填充,我在将缓冲区发送到 C 之前已将其删除。您的帖子(以及 unxnuts 帖子)是我问题的答案!谢谢!
【解决方案2】:

您正在执行array[i] &lt;&lt; 8,这与将array[i] 向左移动8 位或将array[i] 乘以256 相同。这就是您得到巨大数字的原因。摆脱&lt;&lt; 8,你应该没事。

此外,在解除对数组的引用后,类型转换为 int。它应该是(int)array[i]

【讨论】:

  • 这只是一个测试,看看解决方案是否是位移。没有位移也是同样的问题。例如,我的 4x4-bmp (0,0) 中的第一个像素是33620225, 50528770, 67372035,应该是1,1,1...与位移相同的问题。但是解决方案就像您编辑的那样: (int)array[i]
  • 所以好像解决了,去掉bitshifting,因为没有原因,用printf("%d, ", (int)array[i]); 非常感谢!
【解决方案3】:

您将char-指针转换为int-指针,这会导致奇怪的数字。您不需要强制转换它,但如果您必须强制转换结果。像这样:

printf("%d, ", (char)(array[i] << 8)); //B 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 2020-01-24
    相关资源
    最近更新 更多