假设图像是w*h像素,并以真正的"打包"RGB格式存储而没有alpha分量,则每个像素将需要三个字节.
在内存中,图像的第一行可能以令人敬畏的ASCII图形表示,如下所示:
R0 G0 B0 R1 G1 B1 R2 G2 B2 ... R(w-1) G(w-1) B(w-1)
Run Code Online (Sandbox Code Playgroud)
这里,每个R n G n和B n表示单个字节,给出该扫描线的像素n的红色,绿色或蓝色分量.请注意,对于不同的"原始"格式,字节的顺序可能不同; 没有达成一致的世界标准.不同的环境(图形卡,相机......)由于某种原因不同地做,你只需要知道布局.
然后可以通过此函数读取像素:
typedef unsigned char byte;
void get_pixel(const byte *image, unsigned int w,
unsigned int x,
unsigned int y,
byte *red, byte *green, byte *blue)
{
/* Compute pointer to first (red) byte of the desired pixel. */
const byte * pixel = image + w * y * 3 + 3 * x;
/* Copy R, G and B to outputs. */
*red = pixel[0];
*green = pixel[1];
*blue = pixel[2];
}
Run Code Online (Sandbox Code Playgroud)
注意如何使图像的高度不起作用,以及函数如何不受边界检查.生产质量功能可能更具装甲性.
更新如果您担心这种方法太慢,您当然可以循环使用像素,而不是:
unsigned int x, y;
const byte *pixel = /* ... assumed to be pointing at the data as per above */
for(y = 0; y < h; ++y)
{
for(x = 0; x < w; ++x, pixel += 3)
{
const byte red = pixel[0], green = pixel[1], blue = pixel[2];
/* Do something with the current pixel. */
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止发布的方法都不适用于相机"原始"文件.原始文件的文件格式是每个制造商专有的,并且可能包含曝光数据,校准常数和白平衡信息,以及像素数据,这些数据可能采用打包格式,每个像素可能占用多个像素字节,但少于两个.
我确定有开源原始文件转换器程序,你可以咨询找出要使用的算法,但我不知道有什么不在我的脑海里.
只是想到了一个额外的复杂性.原始文件不存储每个像素的RGB值.每个像素仅记录一种颜色.其他两种颜色必须从相邻像素进行插值.找到适合您相机的程序或库肯定会更好.
RAW 图像是一种未压缩的格式,因此您只需指出像素所在的位置(跳过任何可能的标题,然后将像素大小乘以列数乘以行数加上列数),然后然后读取任何二进制数据,为数据布局提供有意义的格式(使用掩码和移位,你知道)。
这是一般过程,对于您当前的格式,您必须检查详细信息。
| 归档时间: |
|
| 查看次数: |
14117 次 |
| 最近记录: |