下面是程序块,,其中alpha为放大缩小倍数,当alpha大于1时,,也就是图像的放大功能可以实现,可是,当alpha在0~1之间时,也就是图像的缩小功能不行,,提示说,堆栈被破坏,或者存在bug....可是放大都可以,缩小时为什么不行,,大家帮忙看看,算法上有没什么不对的。先谢谢了~!inline void ImageScale(CImage *Imgn, CImage *Imgm, double alpha) //非整数倍缩放
{
struct IMAGEPARAMENT P;
RGBQUAD ColorTab[256];
int i, j, nSize;
BYTE **list, *sc;
int Dx, Dy, x1, y1, x2, y2, flag, bpd;
double p, q, a, b, c, d, t1, t2, t3;
if (ImageType(Imgm) == 2) //flag作为标志,当为1时,表示用双线性内插
flag = 1;
else
flag = 0; //为0时,表示用最近邻点法
GetImageParament(Imgm, &P);
Dx = (int) (alpha * P.nWidth);//计算结果位图宽度
Dy = (int) (alpha * P.nHeight);//计算结果位图高度
Imgn -> Destroy();
Imgn ->Create(Dx, Dy, P.nBitCount ); //建立结果位图
bpd = P.nBytesPerPixel;
if (bpd == 1) //256色图像
{
for (i = 0; i < P.nNumColors; i++)
{
GetAllPalette(Imgm, ColorTab);
SetAllPalette(Imgn, ColorTab); //复制调色板
}
}
nSize = (int) ((P.nBytesPerLine + P.nHeight * bpd) * alpha);//计算工作单元大小
sc = (BYTE*) malloc(nSize); //申请像素行工作单元
list = (BYTE**) malloc(Dy * sizeof(BYTE*)); // 申请指针数组
for (i = 0; i < P.nHeight; i++)
list[i] = (BYTE*) Imgm ->GetPixelAddress(0, 0) - i * P.nBytesPerLine;//生成二维数组
for (j = 0; j < Dy; j++)
{
q = j / alpha;
y1 = (int) q;
y2 = y1 + 1;
q = q - y1;
for (i = 0;i < Dx; i++)
{
p = i / alpha;
x1 = (int) p; //x1,y1为整数部分
x2 = x1 + 1;
p = p - x1; //p,q为小数部分
if ((x2 > P.nWidth)||(y2 > P.nHeight )) // 范围检查
continue;
if (x2 == P.nWidth )   x2--;
if (y2 == P.nHeight )  y2--;
if (flag == 0) //flag等于0,采用最近邻点法
{
if (q > 0.5)  y1 = y2;
if (p > 0.5)  x1 = x2;
memcpy(&sc[i * bpd], &list[y1][x1 * bpd],bpd); //从源位图复制像素数据
}
else
{ // flag等于1,双线性内插法
a = (double) list[y1][x1]; //从源位图取数据
b = (double) list[y1][x2];
c = (double) list[y2][x1];
d = (double) list[y2][x2];
t1 = (1 - p) * a + p * b; //双线性内插计算
t2 = (1 - p) * c + p * d;
t3 = (1 - q) * t1 + q * t2;
sc[i] = (BYTE) t3;
}
}
SetRectValue(Imgn, 0, j, Dx, 1, sc); //处理结果总结果位图
}
free(sc); //释放工作单元
free(list);
}

解决方案 »

  1.   

    Dx = (int) (alpha * P.nWidth);//计算结果位图宽度 
    Dy = (int) (alpha * P.nHeight);//计算结果位图高度 
    //错误可能在这里,当alpha 为0到1之间的时候,你计算出的值将永远为0。自己一行一行的调试下好了。
      

  2.   

    Dx = (int) (alpha * P.nWidth + 1);
      

  3.   


    当alpha 为0到1之间的时候,为什么计算出的值将永远为0。提示错误有:HEAP[ghgh.exe]: Heap block at 003BF6C8 modified at 003BFE64 past requested size of 794
    Windows 已在 ghgh.exe 中触发一个断点。其原因可能是堆被损坏,这也说明 ghgh.exe 中或它所加载的任何 DLL 中有 bug。
      

  4.   

    struct IMAGEPARAMENT P; 
    RGBQUAD ColorTab[256]; 
    int i, j, nSize; 
    BYTE **list, *sc; 
    int Dx, Dy, x1, y1, x2, y2, flag, bpd; 
    double p, q, a, b, c, d, t1, t2, t3; 
    if (ImageType(Imgm) == 2) //flag作为标志,当为1时,表示用双线性内插 
    flag = 1; 
    else 
    flag = 0; //为0时,表示用最近邻点法 
    GetImageParament(Imgm, &P); 
    Dx = (int) (alpha * P.nWidth);//计算结果位图宽度 
    Dy = (int) (alpha * P.nHeight);//计算结果位图高度 
    Imgn -> Destroy(); 
    Imgn ->Create(Dx, Dy, P.nBitCount ); //建立结果位图 
    bpd = P.nBytesPerPixel; 
    if (bpd == 1) //256色图像 

    for (i = 0; i < P.nNumColors; i++) 

    GetAllPalette(Imgm, ColorTab); 
    SetAllPalette(Imgn, ColorTab); //复制调色板 


    //修改点一
    nSize = (Dx * P.nBitCount + 31) / 32 * 4;      //(int) ((P.nBytesPerLine + P.nHeight * bpd) * alpha);//计算工作单元大小 
    //
    sc = (BYTE*) malloc(nSize); //申请像素行工作单元 
    //修改点二
    list = (BYTE**) malloc(P.nHeight * sizeof(BYTE*));   //malloc(Dy * sizeof(BYTE*)); // 申请指针数组 
    //
    //修改点三
    for (i = 0; i < P.nHeight; i++) 
    list[i] = (BYTE*) Imgm->GetPixelAddress(0, i); // ->GetPixelAddress(0, 0) - i * P.nBytesPerLine;//生成二维数组 
    //
    for (j = 0; j < Dy; j++) 

    q = j / alpha; 
    y1 = (int) q; 
    y2 = y1 + 1; 
    q = q - y1; 
    for (i = 0;i < Dx; i++) 

    p = i / alpha; 
    x1 = (int) p; //x1,y1为整数部分 
    x2 = x1 + 1; 
    p = p - x1; //p,q为小数部分 
    if ((x2 > P.nWidth)||(y2 > P.nHeight )) // 范围检查 
    continue; 
    if (x2 == P.nWidth )  x2--; 
    if (y2 == P.nHeight )  y2--; 
    if (flag == 0) //flag等于0,采用最近邻点法 

    if (q > 0.5)  y1 = y2; 
    if (p > 0.5)  x1 = x2; 
    memcpy(&sc[i * bpd], &list[y1][x1 * bpd],bpd); //从源位图复制像素数据 

    else 
    { // flag等于1,双线性内插法 
    a = (double) list[y1][x1]; //从源位图取数据 
    b = (double) list[y1][x2]; 
    c = (double) list[y2][x1]; 
    d = (double) list[y2][x2]; 
    t1 = (1 - p) * a + p * b; //双线性内插计算 
    t2 = (1 - p) * c + p * d; 
    t3 = (1 - q) * t1 + q * t2; 
    sc[i] = (BYTE) t3; 


    SetRectValue(Imgn, 0, j, Dx, 1, sc); //处理结果总结果位图 

    free(sc); //释放工作单元 
    free(list); 我修改了一下,在我这可以运行了。
      

  5.   

    //修改点一:看你的程序我理解nSize的值,应该表示目标图像每行像素所占字节数。
        nSize = (Dx * P.nBitCount + 31) / 32 * 4;            //(int) ((P.nBytesPerLine + P.nHeight * bpd) * alpha);//计算工作单元大小 
        //
        sc = (BYTE*) malloc(nSize);  
        //修改点二:list应该对应原始图像数据,list[i]应该指向原始图像第i行数据的起始位置。
        list = (BYTE**) malloc(P.nHeight * sizeof(BYTE*));   //malloc(Dy * sizeof(BYTE*)); // 申请指针数组 
        //
        //修改点三:如点二说的,list[i]指向图像第i行的起始位置。
        for (i = 0; i < P.nHeight; i++) 
            list[i] = (BYTE*) Imgm->GetPixelAddress(0, i);   // ->GetPixelAddress(0, 0) - i * P.nBytesPerLine;//生成二维数组 
      

  6.   

    粗略地看了一下,你的j是整数,这样q = j/alpha这一句的除法会按照整数除法运行,这样q的数值就已经是整数了。y1 = (int)q得到的y1数值和q相同。q最后会变成0。p也同理。
    这样的话你生成的图像质量会有问题吧?因为双线性插值的系数是错误的,生成的结果图像可能和box filtering差不多?