圖片縮放應用(nearest / bilinear / three-order interpolate)

typedef xPixel PIXELCOLORRGB;c++

double Sinxx(double value)
{
if (value < 0) value = -value;orm

if (value < 1.0) {
float temp = value * value;
return 0.5 * temp * value - temp + 2.0 / 3.0;
}
else if (value < 2.0) {
value = 2.0 - value;
value *= value * value;
return value / 6.0;
}
else {
return 0.0;
}
}
int BOUND(int value, int min, int max)
{
chASSERT(min <= max);
if (value <= min)
{
return min;
}
else if (value >= max)
{
return max;
}
else
{
return value;
}get

}it

enum ImageQaulityE
{
IMAGE_GEOMETRY_NEAREST_NEIGHBOR_INTERPOLATE = 0,
IMAGE_GEOMETRY_BILINEAR_INTERPOLATE,
IMAGE_GEOMETRY_THREE_ORDER_INTERPOLATE
};
ImageQaulityE Quality = ImageQaulityE::IMAGE_GEOMETRY_BILINEAR_INTERPOLATE;
PIXELCOLORRGB Interpolate(LPBYTE lpbySrcXY, int x, int y, float fu, float fv, int nScanWidth, int nScanHeight)
{
PIXELCOLORRGB rgb;io

//行字節數, 能夠將dwWidthBytes做爲參數傳遞過來
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;form

switch (Quality)
{
case IMAGE_GEOMETRY_NEAREST_NEIGHBOR_INTERPOLATE:
{
BYTE* pbySrc = lpbySrcXY;
rgb.b = *pbySrc++;
rgb.g = *pbySrc++;
rgb.r = *pbySrc++;
rgb.a = *pbySrc;
break;
}
case IMAGE_GEOMETRY_BILINEAR_INTERPOLATE:
{
//相鄰的四個像素最右下角點的x, y座標偏移量
int nx = 1;
int ny = 1;
if ((x + 1) > (nScanWidth - 1)) nx = 0;
if ((y + 1) > (nScanHeight - 1)) ny = 0;file

//相鄰四個像素的像素值
BYTE abyRed[2][2], abyGreen[2][2], abyBlue[2][2], abyAlpha[2][2];map

//像素點(x, y)的數據位置
BYTE* pbySrc = lpbySrcXY;
//獲取像素數值.
//(x, y) = (x, y) + (0, 0)
abyBlue[0][0] = *pbySrc++;
abyGreen[0][0] = *pbySrc++;
abyRed[0][0] = *pbySrc++;
abyAlpha[0][0] = *pbySrc;float

//(x + 1, y) = (x, y) + (1, 0)
pbySrc = (lpbySrcXY + nx * 4);
abyBlue[1][0] = *pbySrc++;
abyGreen[1][0] = *pbySrc++;
abyRed[1][0] = *pbySrc++;
abyAlpha[1][0] = *pbySrc;im


//指向下一行數據
BYTE* pbySrcTemp = (lpbySrcXY + ny * dwWidthBytes);

//(x , y + 1) = (x, y) + (0, 1)
pbySrc = pbySrcTemp;
abyBlue[0][1] = *pbySrc++;
abyGreen[0][1] = *pbySrc++;
abyRed[0][1] = *pbySrc++;
abyAlpha[0][1] = *pbySrc;

//(x + 1, y + 1) = (x, y) + (1, 1)
pbySrc = pbySrcTemp + (4 * nx);
abyBlue[1][1] = *pbySrc++;
abyGreen[1][1] = *pbySrc++;
abyRed[1][1] = *pbySrc++;
abyAlpha[1][1] = *pbySrc;

rgb.r = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyRed[0][0]) +
(1 - fu) * fv * ((float)abyRed[0][1]) +
fu * (1 - fv) * ((float)abyRed[1][0]) +
fu * fv * ((float)abyRed[1][1])), 0, 255));
rgb.g = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyGreen[0][0]) +
(1 - fu) * fv * ((float)abyGreen[0][1]) +
fu * (1 - fv) * ((float)abyGreen[1][0]) +
fu * fv * ((float)abyGreen[1][1])), 0, 255));

rgb.b = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyBlue[0][0]) +
(1 - fu) * fv * ((float)abyBlue[0][1]) +
fu * (1 - fv) * ((float)abyBlue[1][0]) +
fu * fv * ((float)abyBlue[1][1])), 0, 255));
rgb.a = (BYTE)(BOUND(((1 - fu) * (1 - fv) * ((float)abyAlpha[0][0]) +
(1 - fu) * fv * ((float)abyAlpha[0][1]) +
fu * (1 - fv) * ((float)abyAlpha[1][0]) +
fu * fv * ((float)abyAlpha[1][1])), 0, 255));
break;
}

case IMAGE_GEOMETRY_THREE_ORDER_INTERPOLATE:
{
//像素座標
int xx[4], yy[4];
//相鄰四個像素的像素值
BYTE abyRed[4][4], abyGreen[4][4], abyBlue[4][4], abyAlpha[4][4];

xx[0] = -1; xx[1] = 0; xx[2] = 1; xx[3] = 2;
yy[0] = -1; yy[1] = 0; yy[2] = 1; yy[3] = 2;

//保證合法
if ((x - 1) < 0) xx[0] = 0;
if ((x + 1) > (nScanWidth - 1)) xx[2] = 0;
if ((x + 2) > (nScanWidth - 1)) xx[3] = ((xx[2] == 0) ? 0 : 1);

if ((y - 1) < 0) yy[0] = 0;
if ((y + 1) > (nScanHeight - 1)) yy[2] = 0;
if ((y + 2) > (nScanHeight - 1)) yy[3] = ((yy[2] == 0) ? 0 : 1);

//像素點(x, y)的數據位置
//獲取數據
int i;
for (i = 0; i < 4; i++)
{
//像素點(x, y)的數據位置
BYTE* pbySrcBase = lpbySrcXY + yy[i] * dwWidthBytes;

for (int j = 0; j < 4; j++)
{
BYTE* pbySrc = pbySrcBase + 4 * xx[j];
abyBlue[i][j] = *pbySrc++;
abyGreen[i][j] = *pbySrc++;
abyRed[i][j] = *pbySrc++;
abyAlpha[i][j] = *pbySrc++;
}
}

//u, v向量
float afu[4], afv[4];

afu[0] = Sinxx(1.0f + fu);
afu[1] = Sinxx(fu);
afu[2] = Sinxx(1.0f - fu);
afu[3] = Sinxx(2.0f - fu);

afv[0] = Sinxx(1.0f + fv);
afv[1] = Sinxx(fv);
afv[2] = Sinxx(1.0f - fv);
afv[3] = Sinxx(2.0f - fv);

//矩陣乘向量的中間值
float afRed[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
float afGreen[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
float afBlue[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
float afAlpha[4] = { 0.0f, 0.0f, 0.0f, 0.0f };

for (i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
afRed[i] += afv[j] * abyRed[j][i];
afGreen[i] += afv[j] * abyGreen[j][i];
afBlue[i] += afv[j] * abyBlue[j][i];
afAlpha[i] += afv[j] * abyAlpha[j][i];
}
}
rgb.r = (BYTE)(BOUND((afu[0] * afRed[0] + afu[1] * afRed[1] + afu[2] * afRed[2] +
afu[3] * afRed[3]), 0, 255));
rgb.g = (BYTE)(BOUND((afu[0] * afGreen[0] + afu[1] * afGreen[1] + afu[2] * afGreen[2] +
afu[3] * afGreen[3]), 0, 255));
rgb.b = (BYTE)(BOUND((afu[0] * afBlue[0] + afu[1] * afBlue[1] + afu[2] * afBlue[2] +
afu[3] * afBlue[3]), 0, 255));
rgb.a = (BYTE)(BOUND((afu[0] * afAlpha[0] + afu[1] * afAlpha[1] + afu[2] * afAlpha[2] +
afu[3] * afAlpha[3]), 0, 255));
break;
}
default: break;
}//end switch

return rgb;
}

bool xPixmap::load(const chConstStringA& filename){ QImage img; if(img.load(toQString(filename)) || img.load(QString::fromLocal8Bit(filename.c_ptr(), filename.length()))) { m_bHasAlphaChannel = img.hasAlphaChannel();#if WINDOWS_SYSTEM double nPDI = getCurrentStation().m_dPDI; QSize sizeNew(_X(img.width()), _Y(img.height())); //QSize sizeNew((img.width() * nPDI), (img.height() * nPDI)); if(filename.indexOf("-ext") != -1) { sizeNew = QSize(img.width(), img.height()); } //img = img.scaled(sizeNew, Qt::IgnoreAspectRatio/*, Qt::SmoothTransformation*/);#endif int w = img.width() * nPDI; int h = img.height() * nPDI; setNull(); data().createGraphic(w, h); if (-0.0001 < (nPDI - 1) && (nPDI - 1) < 0.0001) { memcpy((LPVOID)data().pixels(), img.constBits(), w * h * sizeof(xPixel)); } else { xPixel* pImage = (xPixel*)img.constBits(); xPixel* pDst = (xPixel*)data().pixels(); for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) { float fX = x * 1.0 / nPDI; float fY = y * 1.0 / nPDI; xPixel* pSrc = pImage + (int)fY * img.width() + (int)fX; *pDst = Interpolate((LPBYTE)pSrc, int(fX), int(fY), fX - int(fX), fY - int(fY), img.width(), img.height()); ++pDst; } } } return true; } chASSERTx(FALSE, "Faile to load:%s", filename.c_str()); return false;}

相關文章
相關標籤/搜索