缩放,调整 bmp 结构,编程 c
scale, resize bmp structure, programming c
我的任务是用给定的因子缩放 bmp 图片:
stream: base64 bmp 图片编码:
Qk1CAAAAAAAAADYAAAAoAAAABAAAAAEAAAABABgAAAAAAAwAAAAjLgAAIy4AAAAAAAAAAAAA/////wAAAP8AAAAA
scale.c
struct bmp_image* scale(const struct bmp_image* image, float factor){
if(image == NULL || factor <= 0){
return NULL;
}
.........
int width = bmp->header->width;
int height = bmp->header->height;
int widthNew = (int)round((float)width * factor);
int heightNew = (int)round((float)height * factor);
for (uint32_t y = 0; y < heightNew; y++){
for(uint32_t z = 0; z< widthNew; z++){
bmp->data[(y*widthNew)+z].red=image->data[(int)(floor((float)y/(float)factor)*width+floor((float)z/(float)factor))].red;
bmp->data[(y*widthNew)+z].green=image->data[(int)(floor((float)y/(float)factor)*width+floor((float)z/(float)factor))].green;
bmp->data[(y*widthNew)+z].blue=image->data[(int)(floor((float)y/(float)factor)*width+floor((float)z/(float)factor))].blue;
}
}
return bmp;
}
main.c
FILE *output_p8 = fopen("scale.bmp", "w");
struct bmp_image* newimage8 = NULL;
newimage8 = scale(image, 1.025656);
free_bmp_image(image);
write_bmp(output_p8,newimage8);
free_bmp_image(newimage8);
fclose(output_p8);
数据输出我之后得到的:
ffffff ffffff ff0000 00ff00
我应该有的数据:
ffffff ff0000 00ff00 000000
有什么建议吗?
计算新维度时,进行浮点计算,然后四舍五入为最接近的整数:
int widthNew = round(width * factor);
(您不需要强制转换:factor
是一个 float
,整数与 float
相乘的结果也是一个 float
; widthNew
是一个整数,因此 float
结果必须转换为整数。)
因为你四舍五入,你的有效比例因子(我们称之为factor_eff
)可能与标称值不同factor
:
float factor_eff = (float) widthNew / width;
你的情况:
factor == 1.025656;
width == 4;
widthNew == round(1.025656 * 4) == round(4.102624) == 4;
factor_eff = 4.0 / 4 == 1.0;
但是您使用旧因子进行指数计算:
int zNew = floor(z / factor);
(同样,您不需要转换。)对于您的四个 z 索引,这将产生:
z == 0; zNew == floor(0 / 1.025656) == floor(0.0) == 0; // ok
z == 1; zNew == floor(1 / 1.025656) ~~ floor(0.9749858) == 0; // ! should be 1
z == 2; zNew == floor(2 / 1.025656) ~~ floor(1.9499715) == 1; // ! should be 2
z == 3; zNew == floor(3 / 1.025656) ~~ floor(2.9249573) == 2; // ! should be 3
您可以修复浮点因子,但我认为使用整数算法计算新索引更好(也更快):
int zNew = z * width / widthNew;
int yNew = y * height / heightNew;
确保先做乘法。这种方法应该可以安全地用于高达 46,000 的尺寸。
我的任务是用给定的因子缩放 bmp 图片:
stream: base64 bmp 图片编码:
Qk1CAAAAAAAAADYAAAAoAAAABAAAAAEAAAABABgAAAAAAAwAAAAjLgAAIy4AAAAAAAAAAAAA/////wAAAP8AAAAA
scale.c
struct bmp_image* scale(const struct bmp_image* image, float factor){
if(image == NULL || factor <= 0){
return NULL;
}
.........
int width = bmp->header->width;
int height = bmp->header->height;
int widthNew = (int)round((float)width * factor);
int heightNew = (int)round((float)height * factor);
for (uint32_t y = 0; y < heightNew; y++){
for(uint32_t z = 0; z< widthNew; z++){
bmp->data[(y*widthNew)+z].red=image->data[(int)(floor((float)y/(float)factor)*width+floor((float)z/(float)factor))].red;
bmp->data[(y*widthNew)+z].green=image->data[(int)(floor((float)y/(float)factor)*width+floor((float)z/(float)factor))].green;
bmp->data[(y*widthNew)+z].blue=image->data[(int)(floor((float)y/(float)factor)*width+floor((float)z/(float)factor))].blue;
}
}
return bmp;
}
main.c
FILE *output_p8 = fopen("scale.bmp", "w");
struct bmp_image* newimage8 = NULL;
newimage8 = scale(image, 1.025656);
free_bmp_image(image);
write_bmp(output_p8,newimage8);
free_bmp_image(newimage8);
fclose(output_p8);
数据输出我之后得到的:
ffffff ffffff ff0000 00ff00
我应该有的数据:
ffffff ff0000 00ff00 000000
有什么建议吗?
计算新维度时,进行浮点计算,然后四舍五入为最接近的整数:
int widthNew = round(width * factor);
(您不需要强制转换:factor
是一个 float
,整数与 float
相乘的结果也是一个 float
; widthNew
是一个整数,因此 float
结果必须转换为整数。)
因为你四舍五入,你的有效比例因子(我们称之为factor_eff
)可能与标称值不同factor
:
float factor_eff = (float) widthNew / width;
你的情况:
factor == 1.025656;
width == 4;
widthNew == round(1.025656 * 4) == round(4.102624) == 4;
factor_eff = 4.0 / 4 == 1.0;
但是您使用旧因子进行指数计算:
int zNew = floor(z / factor);
(同样,您不需要转换。)对于您的四个 z 索引,这将产生:
z == 0; zNew == floor(0 / 1.025656) == floor(0.0) == 0; // ok
z == 1; zNew == floor(1 / 1.025656) ~~ floor(0.9749858) == 0; // ! should be 1
z == 2; zNew == floor(2 / 1.025656) ~~ floor(1.9499715) == 1; // ! should be 2
z == 3; zNew == floor(3 / 1.025656) ~~ floor(2.9249573) == 2; // ! should be 3
您可以修复浮点因子,但我认为使用整数算法计算新索引更好(也更快):
int zNew = z * width / widthNew;
int yNew = y * height / heightNew;
确保先做乘法。这种方法应该可以安全地用于高达 46,000 的尺寸。