bmp文件太大了,有几百兆以上,怎样对这种图像进行分块显示和放大缩小?以前有人提示,首先得到窗口的大小,然后以窗口的长宽参数,写一个bmp的文件头,然后把原文件的块装入内存并显示,但是我写不出读原文件块的程序。
请高手帮帮我。

解决方案 »

  1.   

    操作巨型BMP 得要海量内存的 机器 和快速的 硬盘,不然会很慢的. 
    最好还要好的图形硬件. 这就是为什么平面设计的机器都这么贵的原因.
      

  2.   

    一般机器上也可以读的,比如说acdsee就可以读300兆以上的图形,用的技术就是把原图像分块读到内存中,然后显示出来。哪位朋友有代码,我可以提供大图像进行测试。
      

  3.   

    以前是用顺序读取得方式,比较大的文件最好用文件映射的方式,读取原理如下
    CRect rect(0,0,100,100);
    GetClientRect(&rect);
    FILE *fp=fopen(szBmpFile,"rb");
    if(!fp)return;
    fseek(fp,sizeof(BITMAPFILEHEADER),SEEK_SET);
    BITMAPINFOHEADER bmihSrc;
    fread(&bmihSrc,sizeof(bmihSrc),1,fp);
    if(bmihSrc.biBitCount<=8)return;
    int nStribeSrc = DIBWIDTHBYTES(bmihSrc); BITMAPINFOHEADER  bmihDst=bmihSrc;  
    bmihDst.biWidth = rect.Width();// & ~3;
    bmihDst.biHeight = rect.Height();
    int nStribeDst = DIBWIDTHBYTES(bmihDst);
    bmihDst.biSizeImage = nStribeDst * bmihDst.biHeight;

    HANDLE hDib  =  GlobalAlloc(GHND,bmihDst.biSizeImage  +  sizeof(BITMAPINFOHEADER));    
    LPBITMAPINFOHEADER lpbi  =  (LPBITMAPINFOHEADER)GlobalLock(hDib); 
    *lpbi  =  bmihDst;   
    LPBYTE pbBits = (LPBYTE)(lpbi+1);
    int nDataStart = ftell(fp);
    //#define _SET
    int byteUnit = bmihDst.biBitCount>>3;
    for(int y=0;y<bmihDst.biHeight;++y)
    {
    int ySrc = MulDiv(y,bmihSrc.biHeight,bmihDst.biHeight);
    if(ySrc>bmihSrc.biHeight)ySrc=bmihSrc.biHeight;
    #ifndef _SET
    if(int n = nDataStart+ySrc*nStribeSrc - ftell(fp))
    fseek(fp,n,SEEK_CUR);
    #endif
    int xLast = -1;
    for(int x=0;x<bmihDst.biWidth;++x)
    {
    int xSrc = MulDiv(x,bmihSrc.biWidth,bmihDst.biWidth);
    if(xSrc>bmihSrc.biWidth)xSrc=bmihSrc.biWidth;
    #ifdef _SET
    fseek(fp,nDataStart+ySrc*nStribeSrc+xSrc*byteUnit,SEEK_SET);
    #else
    fseek(fp,(xSrc-xLast-1)*byteUnit,SEEK_CUR);
    xLast = xSrc;
    #endif
    fread(pbBits,byteUnit,1,fp);
    pbBits +=byteUnit;
    }
    if(nStribeDst != bmihDst.biWidth*byteUnit)
    pbBits += nStribeDst - bmihDst.biWidth*byteUnit;
    }
    pbBits = (LPBYTE)(lpbi+1);
    #ifdef _TEST
    HDRAWDIB hdd = DrawDibOpen();
    DrawDibDraw(hdd,hdc,
    0,0,bmihDst.biWidth,bmihDst.biHeight,
    &bmihDst,pbBits,
    0,0,bmihDst.biWidth,bmihDst.biHeight, 
    0);
    DrawDibClose(hdd);
    #endif
    GlobalUnlock(hDib);    
    GlobalFree(hDib);
      

  4.   

    这段代码没读懂,能解释一下吗?
    //说明比特数/象素,其值为1、4、8、16、24、或32
    int byteUnit = bmihDst.biBitCount>>3; for(int y=0;y<bmihDst.biHeight;++y)
    {
    //The MulDiv function multiplies two 32-bit values and then divides 
    //the 64-bit result by a third 32-bit value. The return value is 
    //rounded up or down to the nearest integer.  int ySrc = MulDiv(y,bmihSrc.biHeight,bmihDst.biHeight);
    if(ySrc>bmihSrc.biHeight)ySrc=bmihSrc.biHeight;
    #ifndef _SET
    if(int n = nDataStart+ySrc*nStribeSrc - ftell(fp))
    fseek(fp,n,SEEK_CUR);
    #endif
    int xLast = -1;
    for(int x=0;x<bmihDst.biWidth;++x)
    {
    int xSrc = MulDiv(x,bmihSrc.biWidth,bmihDst.biWidth);
    if(xSrc>bmihSrc.biWidth)xSrc=bmihSrc.biWidth;
    #ifdef _SET
    fseek(fp,nDataStart+ySrc*nStribeSrc+xSrc*byteUnit,SEEK_SET);
    #else
    fseek(fp,(xSrc-xLast-1)*byteUnit,SEEK_CUR);
    xLast = xSrc;
    #endif
    fread(pbBits,byteUnit,1,fp);
    pbBits +=byteUnit;
    }
    if(nStribeDst != bmihDst.biWidth*byteUnit)
    pbBits += nStribeDst - bmihDst.biWidth*byteUnit;
    }
    pbBits = (LPBYTE)(lpbi+1);
      

  5.   

    //每个点对应字节数,如32bit=4Byte
    int byteUnit = bmihDst.biBitCount>>3;
    //一行一行得取
    for(int y=0;y<bmihDst.biHeight;++y)
    {
    //y*bmihSrc.biHeight/bmihDst.biHeight,即比例尺变化
    int ySrc = MulDiv(y,bmihSrc.biHeight,bmihDst.biHeight);
    //判断是否越界,若越界,取最大值
    if(ySrc>bmihSrc.biHeight)ySrc=bmihSrc.biHeight;
    #ifndef _SET
    //移动到当前行ySrc的位置
    if(int n = nDataStart+ySrc*nStribeSrc - ftell(fp))
    fseek(fp,n,SEEK_CUR);
    #endif
    int xLast = -1;
    //一列一列得取
    for(int x=0;x<bmihDst.biWidth;++x)
    {
    //x*bmihSrc.biWidth/bmihDst.biWidth,即比例尺变化
    int xSrc = MulDiv(x,bmihSrc.biWidth,bmihDst.biWidth);
    //判断是否越界,若越界,取最大值
    if(xSrc>bmihSrc.biWidth)xSrc=bmihSrc.biWidth;
    #ifdef _SET
    //直接定位到xSrc,ySrc对应位置,nStribeSrc为每行步长
    fseek(fp,nDataStart+ySrc*nStribeSrc+xSrc*byteUnit,SEEK_SET);
    #else
    //跳过xSrc-xLast-1个点的长度,每点所花字节byteUnit
    fseek(fp,(xSrc-xLast-1)*byteUnit,SEEK_CUR);
    //记录上一个位置
    xLast = xSrc;
    #endif
    //读出一点的数据
    fread(pbBits,byteUnit,1,fp);
    //指针向前移一点
    pbBits +=byteUnit;
    }
    //如果每行步长和所写的长度不符
    if(nStribeDst != bmihDst.biWidth*byteUnit)
    //则对应向前移相应长度
    pbBits += nStribeDst - bmihDst.biWidth*byteUnit;
    }
    //写入完毕,设置pbBits为数据起点
    pbBits = (LPBYTE)(lpbi+1);