以文本方式查看主题

-  计算机科学论坛  (http://bbs.xml.org.cn/index.asp)
--  『 C/C++编程思想 』  (http://bbs.xml.org.cn/list.asp?boardid=61)
----  Win32 C Function for High-Quality Bitmap Shrinking  (http://bbs.xml.org.cn/dispbbs.asp?boardid=61&rootid=&id=51937)


--  作者:卷积内核
--  发布时间:8/29/2007 11:09:00 AM

--  Win32 C Function for High-Quality Bitmap Shrinking
Therefore, I wrote my own function (ShrinkBitmap) to give me the ability to shink and expand images in my own application, yet do so with the same quality I would expect from a graphics package. Take a look at the following table of images and you'll see first a large image (the original) and then a comparison of images that have been shrunk using the StretchBlt function, my ShrinkBitmap function and the an Adobe Photoshop conversion. As you can see, ShrinkBitmap gives you Adobo Photoshop bitmap shrinking capabilities from within your own application.

按此在新窗口浏览图片
This is me in original size and I'm going to shrink myself  


Resolution StretchBlt My function Adobe Photoshop
105 × 150 按此在新窗口浏览图片 按此在新窗口浏览图片 按此在新窗口浏览图片
35 × 50 按此在新窗口浏览图片 按此在新窗口浏览图片 按此在新窗口浏览图片


Source Code
Place these macros into the beginning of your program:
#define Alloc(p,t) (t *)malloc((p)*sizeof(t))
#define For(i,n) for ((i)=0;(i)<(n);(i)++)
#define iFor(n) For (i,n)
#define jFor(n) For (j,n)

And also this type-definition:
typedef struct {
WORD x,y;  // dimensions
WORD l;    // bytes per scan-line (32-bit allignment)
BYTE *b;   // bits of bitmap,3 bytes/pixel, BGR
} tWorkBMP;  // 24-bit working bitmap

The functions also require the header file for memory allocation, or you can rewrite them to use keywords new and delete.
#include <malloc.h>

Here's the actual ShrinkBitmap function
HBITMAP ShrinkBitmap (HBITMAP a,WORD bx,WORD by)
// creates and returns new bitmap with dimensions of
// [bx,by] by shrinking bitmap a both [bx,by] must be less or equal
// than the dims of a, unless the result is nonsense
{
tWorkBMP in,out;
HBITMAP b=CreateEmptyBitmap(bx,by);
OpenBitmapForWork (a,&in);
ShrinkWorkingBitmap (&in,&out,bx,by);
free (in.b);
SaveWorkingBitmap (&out,b);
free (out.b);
return (b);
}

The following functions are just supporting and I recommend treating them in "black box" fashion. But you have to place them in front of the ShrinkBitmap function or forward declare them.
void CreateWorkingBitmap (WORD dx,WORD dy,tWorkBMP *w)
{
w->x=dx;
w->y=dy;
w->l=(dx+1)*3&0xfffc;
w->b=Alloc(w->l*dy,BYTE);
}

HBITMAP CreateEmptyBitmap (WORD dx,WORD dy)
{
HDC h=GetDC(NULL);
HBITMAP b=CreateCompatibleBitmap(h,dx,dy);
ReleaseDC (NULL,h);

return (b);
}

void SetBMIHeader (BITMAPINFO *b,short dx,short dy)
{
b->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
b->bmiHeader.biWidth=dx;
b->bmiHeader.biHeight=-dy;
b->bmiHeader.biPlanes=1;
b->bmiHeader.biBitCount=24;
b->bmiHeader.biCompression=BI_RGB;
b->bmiHeader.biSizeImage=0;
b->bmiHeader.biXPelsPerMeter=1;
b->bmiHeader.biYPelsPerMeter=1;
b->bmiHeader.biClrUsed=0;
b->bmiHeader.biClrImportant=0;
}

void SaveWorkingBitmap (tWorkBMP *w,HBITMAP b)
{
BITMAPINFO s;
HDC h=GetDC(NULL);
SetBMIHeader (&s,w->x,w->y);
SetDIBits (h,b,0,w->y,w->b,&s,DIB_RGB_COLORS);
ReleaseDC (NULL,h);
}

void ShrinkWorkingBitmap (tWorkBMP *a,tWorkBMP *b,WORD bx,WORD by)
{
BYTE *uy=a->b,*ux,i;
WORD x,y,nx,ny=0;
DWORD df=3*bx,nf=df*by,j;
float k,qx[2],qy[2],q[4],*f=Alloc(nf,float);

CreateWorkingBitmap (bx,by,b);

jFor (nf) f[j]=0;
j=0;

For (y,a->y) {
  ux=uy;
  uy+=a->l;
  nx=0;
  ny+=by;

  if (ny>a->y) {

   qy[0]=1-(qy[1]=(ny-a->y)/(float)by);

   For (x,a->x) {

    nx+=bx;

    if (nx>a->x) {
     qx[0]=1-(qx[1]=(nx-a->x)/(float)bx);

     iFor (4) q[i]=qx[i&1]*qy[i>>1];

     iFor (3) {
      f[j]+=(*ux)*q[0];
      f[j+3]+=(*ux)*q[1];
      f[j+df]+=(*ux)*q[2];
      f[(j++)+df+3]+=(*(ux++))*q[3];
     }
    }
    else iFor (3) {
     f[j+i]+=(*ux)*qy[0];
     f[j+df+i]+=(*(ux++))*qy[1];
    }
    if (nx>=a->x) nx-=a->x;
     if (!nx) j+=3;
   }
  }
  else {
   For (x,a->x) {

    nx+=bx;

    if (nx>a->x) {
     qx[0]=1-(qx[1]=(nx-a->x)/(float)bx);
     iFor (3) {
      f[j]+=(*ux)*qx[0];
      f[(j++)+3]+=(*(ux++))*qx[1];
     }
    }
    else iFor (3) f[j+i]+=*(ux++);

    if (nx>=a->x) nx-=a->x;
     if (!nx) j+=3;
   }
   if (ny<a->y) j-=df;
  }
  if (ny>=a->y) ny-=a->y;
}

nf=0;
k=bx*by/(float)(a->x*a->y);
uy=b->b;

For (y,by) {
  jFor (df) uy[j]=f[nf++]*k+.5;
  uy+=b->l;
}

free (f);
}


--  作者:v.O.x
--  发布时间:8/29/2007 11:26:00 AM

--  
open bitmap func missed
W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
62.500ms