我整晚都在敲打这段代码。我正在尝试在 ESP32 CAM 上裁剪位图。我拍了一张照片,将照片转换为 bmp,然后调用以下函数:
size_t crop_image(uint8_t *fb, size_t len, uint32_t width, uint32_t height, unsigned short crop_left, unsigned short crop_top, unsigned short crop_width, unsigned short crop_height)
{
uint8_t *buf = fb + BMP_HEADER_LEN;
size_t new_size = crop_width * crop_height * 3 + BMP_HEADER_LEN;
unsigned int write_idx = 0;
for(uint32_t y = crop_top * 3; y < (crop_top + crop_height) * width * 3; y += width * 3){
for(int x = crop_left * 3; x < (crop_left + crop_width) * 3; x += 3){
int pix_idx = x + y;
buf[write_idx++] = buf[pix_idx];
buf[write_idx++] = buf[pix_idx+1];
buf[write_idx++] = buf[pix_idx+2];
}
}
// Adjust the BMP Header
*(uint32_t *)(fb + BMP_HEADER_WIDTH_OFFSET) = crop_width;
*(uint32_t *)(fb + BMP_HEADER_HEIGHT_OFFSET) = -1 * crop_height;
*(uint32_t *)(fb + 6) = new_size;
*(uint32_t *)(fb + 34) = crop_width * crop_height * 3;
return new_size;
}
这几乎可以工作。如果我将图像的宽度和高度作为crop_width 和crop_height 参数传递,则输出与原始参数相同。如果我通过较小的高度和全宽,那么它也可以工作。当我传入一个小于原始宽度的crop_width 时,我得到一个图像,其对角线“移位”线从右上角延伸到底部约1/3 处。看起来我的宽度偏离了一个字节,导致 3/2 斜线。但我无法弄清楚是什么原因。
我附上了一个全尺寸的 jpg 和一个裁剪的位图。请注意,jpg 不是源(我的代码不保存原件),但与裁剪图像的源非常相似。裁剪后的 bmitmap 是通过使用crop_left = 0、crop_top = 0、crop_width = 799、crop_height = 600 的调用创建的。原始图像为 800x600。
我已经删除了所有额外的代码 - 所以没有错误处理,没有从位图标题中提取宽度/高度等。
代码如此简单,这让我发疯。谢谢