BMP位图任意放大 和缩小,c++ 源代码发放了哈
前几天碰上需要对bmp位图进行缩放的功能,
调用API函数,虽然能实现位图缩放,但是对有放大的效果好,缩小会造成失真,图像上有花点,让人难以接受
,因为本人以前学易语言,易语言有一段代码,对bmp图像缩放效果非常 好,
昨天抽空,把它翻译成c++代码了,经验证,非常 好用,帖上代码:
这一段是对宽度进行缩放:
void __stdcall bmpsetH(unsigned char *bitmap,int h,unsigned char *bitmap2)
{
int i,j,k,bitmapH1,bitmapH2,bitmapV1,bitmapV2,bitmapSize1,bitmapSize2,bitmapLen1,bitmapLen2;
int startH1,startH2,R,G,B,R1,G1,B1;
// 位图宽1 = 取字节集数据 (位图数据, #整数型, 19)
bitmapH1=*((int*)(bitmap+18));
bitmapV1=*((int*)(bitmap+22));
int redress1=bitmapH1%4;
int bitmapNH1=bitmapH1*3+redress1;
bitmapLen1=bitmapNH1*bitmapV1;
bitmapSize1=bitmapLen1+54;
int redress2=h%4;
int bitmapNH2=h*3+redress2;
bitmapLen2=bitmapNH2*bitmapV1;
bitmapSize2=bitmapLen2+54;
memcpy(bitmap2,bitmap,54);
memcpy(bitmap2+2,&bitmapSize2,4);
memcpy(bitmap2+18,&h,4);
double Hval=(double)bitmapH1/h;
double Hvala=0;
int Hvalb=0,Hvalc=0;
for (i=1;i<=bitmapV1;i++)
{
startH2=bitmapSize2-i*bitmapNH2;
startH1=bitmapSize1-i*bitmapNH1;
B1=bitmap[startH1];
G1=bitmap[startH1+1];
R1=bitmap[startH1+2];
for(j=1;j<=h;j++)
{
startH2=startH2+3;
Hvala=Hvala+Hval;
if (Hvala<1)
{
Hvalb=3;
}
else
{
Hvalc=Hvala;
Hvalb=Hvalc*3;
}
startH1=bitmapSize1-i*bitmapNH1+Hvalb;
B=(bitmap[startH1-3]+B1)/2;
G=(bitmap[startH1-2]+G1)/2;
R=(bitmap[startH1-1]+R1)/2;
bitmap2[startH2-3]=B;
bitmap2[startH2-2]=G;
bitmap2[startH2-1]=R;
B1=bitmap[startH1-3];
G1=bitmap[startH1-2];
R1=bitmap[startH1-1];
}
Hvala=0;
}
}
这一段是对高度进行缩放:
void BmpSetV(unsigned char *bitmap,int v,unsigned char *bitmap2)
{
double Vval,Vvala=0;
int i,j,Vvalb=0,bitH1,bitNH1,bitV1,redress,bitLen1,bitsize1,bitLen2,bitsize2;
int start3=0,start2=0,start1=0,G1,B1,R1,R,G,B;
bitH1=*((int*)(bitmap+18));
bitV1=*((int*)(bitmap+22));
redress=bitH1%4;
bitNH1=bitH1*3+redress;
bitLen1=bitNH1*bitV1;
bitsize1=bitLen1+54;
bitLen2=bitNH1*v;
bitsize2=bitLen2+54;
memcpy(bitmap2,bitmap,54);
memcpy(bitmap2+2,&bitsize2,4);
memcpy(bitmap2+22,&v,4);
Vval=bitV1/(double)v;
for (i=1;i<=bitH1;i++)
{
start3=bitsize1-bitNH1+i*3;
B1=bitmap[start3-3];
G1=bitmap[start3-2];
R1=bitmap[start3-1];
for (j=1;j<=v;j++)
{
Vvala=Vvala+Vval;
if (Vvala<1)Vvalb=1;
else Vvalb=Vvala;
start2=bitsize2-j*bitNH1+i*3;
start1=bitsize1-Vvalb*bitNH1+i*3;
if (Vvalb<bitV1)
{
start3=bitsize1-Vvalb*bitNH1-bitNH1+i*3;
if(i==1)
{
bitmap2[start2-3]=bitmap[start1-3];
bitmap2[start2-2]=bitmap[start1-2];
bitmap2[start2-1]=bitmap[start1-1];
}
else
{
B=(B1+bitmap[start1-3])/2;
G=(G1+bitmap[start1-2])/2;
R=(R1+bitmap[start1-1])/2;
bitmap2[start2-3]=B;
bitmap2[start2-2]=G;
bitmap2[start2-1]=R;
B1=bitmap[start3-3];
G1=bitmap[start3-2];
R1=bitmap[start3-1];
}
}
else
{
bitmap2[start2-3]=bitmap[start1-3];
bitmap2[start2-2]=bitmap[start1-2];
bitmap2[start2-1]=bitmap[start1-1];
}
}
Vvala=0;
}
}
示例:
int main(int argc, char* argv[])
{
unsigned char *bmp,*bmp2;
bmp=(unsigned char*)malloc(1244214);
bmp2=(unsigned char*)malloc(1244214);
FILE *fp=fopen("D:\\开机画面.bmp","rb");
fread(bmp,1,304182,fp);
fclose(fp);
//bmpsetH(bmp,720,bmp2);
// memcpy(bmp,bmp2,1244214);
BmpSetV(bmp,290,bmp2);
fp=fopen("D:\\开机.bmp","wb");
fwrite(bmp2,1,1244214,fp);
fclose(fp);
free(bmp);
free(bmp2);
return 0;
}
[解决办法]
缩小的时候,如果是按比例采样,失真会大一些;如果对周围区域的点取平均,效果会相对好一些
[解决办法]