在C中解包(r,g,b)原始像素缓冲区

时间:2013-04-11 17:33:44

标签: python c arrays bitmap ctypes

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

现在我要做的是从Bitmap(bmp文件)中取出pixelbuffer,将其发送到C函数,将原始缓冲区转换为R,G,B值的平面数组并返回到python。但是当我试图将“缓冲区”转换为R,G,B值时,我陷入了困境。 在python中,我只需使用“struct”-module: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;
}

3 个答案:

答案 0 :(得分:5)

您在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会不包括填充。

答案 1 :(得分:2)

您正在执行array[i] << 8,这与向左移动array[i] 8位,或将array[i]乘以256相同。这就是为什么您得到的数字很大。摆脱<< 8,你应该没问题。

此外,在取消引用数组后,将类型转换为int。它应该是(int)array[i]

答案 2 :(得分:0)

你正在将char - 指针转换为int - 指针,这会导致奇怪的数字。你不应该抛出它,但如果你必须施放结果。像这样:

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