typedef xPixel PIXELCOLORRGB;

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

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;
}

}

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;

//行字节数, 可以将dwWidthBytes作为参数传递过来
DWORD dwWidthBytes = (DWORD)nScanWidth * 4;

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;

//相邻四个像素的像素值
BYTE abyRed[2][2], abyGreen[2][2], abyBlue[2][2], abyAlpha[2][2];

//像素点(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;

//(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;

//指向下一行数据
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;
}

图片缩放应用(nearest / bilinear / three-order interpolate)的更多相关文章

  1. CSS实现图片缩放特效

    今天是感恩节,祝大家感恩节快乐哦!最近天冷了,大家注意保暖哟.下面一起看看小颖写的demo吧. html代码: <!DOCTYPE html> <html> <head& ...

  2. HTML5 图片缩放功能

    腾讯新闻上用的插件(xw.qq.com) 缩放插件scale.js (function(window, undefined) { var document = window.document, sup ...

  3. PHP图片裁剪_图片缩放_PHP生成缩略图

    在制作网页过程中,为了排版整齐美观,对网页中的图片处理成固定大小尺寸的图片,或是要截去图片边角中含有水印的图片,对于图片量多,每天更新大量图,靠人工PS处理是不现实的,那么有没有自动处理图片的程序了! ...

  4. iOS开发UI篇—UIScrollView控件实现图片缩放功能

    iOS开发UI篇—UIScrollView控件实现图片缩放功能 一.缩放 1.简单说明: 有些时候,我们可能要对某些内容进行手势缩放,如下图所示 UIScrollView不仅能滚动显示大量内容,还能对 ...

  5. UISlider显示进度(并且实现图片缩放)

    图片展示效果如下: 其他没什么好说的,直接上代码: RootView.h: #import <UIKit/UIKit.h> @interface RootView : UIView @pr ...

  6. Android图片缩放方法

    安卓开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法: 方法1:按固定比例进行缩放 在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们 ...

  7. Android安卓开发中图片缩放讲解

    安卓开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法: 方法1:按固定比例进行缩放 在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们 ...

  8. Asp.net 实现图片缩放 无水印(方法一)

    /// <summary> /// 图片缩放 无水印 /// </summary> /// <param name="sourceFile">图 ...

  9. android关于图片缩放

    网上有许多关于图片缩放的demo,本人都感觉不怎么好用,最近在github看到了 一个简单的支持多指缩放图片的Android View类 gesture-imageview (地址:https://g ...

  10. UIScrollView 之图片缩放

    UIScrollView 之图片缩放 有些时候,我们可能要对某些内容进行手势缩放,如下图所示 UIScrollView不仅能滚动显示大量内容,还能对其内容进行缩放处理 也就是说,要完成缩放功能的话,只 ...

随机推荐

  1. 虚拟机中CentOS 7下PHP环境配置

    为了简单起见,虚拟机网卡设置为桥接模式 1.yum install  httpd php 2.yum install mariadb 3.启动mariadb systemctl start maria ...

  2. eaby技术架构变迁

    如果你对项目管理.系统架构有兴趣,请加微信订阅号"softjg",加入这个PM.架构师的大家庭 最近在infoq上面看到 ebay介绍其系统架构变迁以及系统设计分享方面的讲座,其中 ...

  3. msChart组件安装与编程

    首先下载mschart.ocx文件,至于它所依赖的.net环境,网上有很多,本人下载的插件给出链接,http://www.cr173.com/soft/47300.html而它所依赖的环境可以从我的云 ...

  4. qt 环境下mapx组件打包后编译产生c2248和c2512错误

    C:\Qt\Qt5.6.0\5.6\msvc2013\include\QtCore\qmetatype.h:760: error: C2248: “MapSpace::IRowCursor::IRow ...

  5. asp.net中如何调取数据库中存储过程输出的两个变量

    public DataTable GetList_GenqtyNumPrice(int _peoid, int _genstorageid,int _goodsid) { DataSet ds = n ...

  6. java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

    报这个错是因为加的struts的jar包有问题... 另外,jar包应该放在WEB-INF下的lib文件夹里面,且不必Add to build path,该目录下的jar包会自动引入 使用struts ...

  7. 正则表达式test验证的“bug”

    在使用正则表达式对某些字符串进行验证时,我们常常会使用到test方法,而该方法也隐藏着一个陷阱,今天就让我们来看一下这个问题. var str = 'hello jack, hello rose'; ...

  8. jquery操作复选框(checkbox)的12个小技巧总结

    1.获取单个checkbox选中项(三种写法)$("input:checkbox:checked").val()或者$("input:[type='checkbox']: ...

  9. 【MySQL】编译安装

    安装所需环境: yum install cmake make glibc gcc gcc-c++ libstdc++* sysstat lrzsz libtool libxml* libtool-lt ...

  10. 向IPython Notebook中导入.py文件

    IPython Notebook使用起来简洁方便,但是有时候如果需要导入一个现有的.py文件,则需要注意选择导入的方法以达到不同的效果.目前遇到3种方法. (1) 将文件保存为.ipynb格式,直接拖 ...