图片缩放应用(nearest / bilinear / three-order interpolate)
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)的更多相关文章
- CSS实现图片缩放特效
今天是感恩节,祝大家感恩节快乐哦!最近天冷了,大家注意保暖哟.下面一起看看小颖写的demo吧. html代码: <!DOCTYPE html> <html> <head& ...
- HTML5 图片缩放功能
腾讯新闻上用的插件(xw.qq.com) 缩放插件scale.js (function(window, undefined) { var document = window.document, sup ...
- PHP图片裁剪_图片缩放_PHP生成缩略图
在制作网页过程中,为了排版整齐美观,对网页中的图片处理成固定大小尺寸的图片,或是要截去图片边角中含有水印的图片,对于图片量多,每天更新大量图,靠人工PS处理是不现实的,那么有没有自动处理图片的程序了! ...
- iOS开发UI篇—UIScrollView控件实现图片缩放功能
iOS开发UI篇—UIScrollView控件实现图片缩放功能 一.缩放 1.简单说明: 有些时候,我们可能要对某些内容进行手势缩放,如下图所示 UIScrollView不仅能滚动显示大量内容,还能对 ...
- UISlider显示进度(并且实现图片缩放)
图片展示效果如下: 其他没什么好说的,直接上代码: RootView.h: #import <UIKit/UIKit.h> @interface RootView : UIView @pr ...
- Android图片缩放方法
安卓开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法: 方法1:按固定比例进行缩放 在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们 ...
- Android安卓开发中图片缩放讲解
安卓开发中应用到图片的处理时候,我们通常会怎么缩放操作呢,来看下面的两种做法: 方法1:按固定比例进行缩放 在开发一些软件,如新闻客户端,很多时候要显示图片的缩略图,由于手机屏幕限制,一般情况下,我们 ...
- Asp.net 实现图片缩放 无水印(方法一)
/// <summary> /// 图片缩放 无水印 /// </summary> /// <param name="sourceFile">图 ...
- android关于图片缩放
网上有许多关于图片缩放的demo,本人都感觉不怎么好用,最近在github看到了 一个简单的支持多指缩放图片的Android View类 gesture-imageview (地址:https://g ...
- UIScrollView 之图片缩放
UIScrollView 之图片缩放 有些时候,我们可能要对某些内容进行手势缩放,如下图所示 UIScrollView不仅能滚动显示大量内容,还能对其内容进行缩放处理 也就是说,要完成缩放功能的话,只 ...
随机推荐
- 两系统用asp.net forms 身份验证方式实现跨域登录信息共享
1.两个系统的 web.config 都配置为 forms 验证方式( system.web —> authentication 节点) 2.在两个系统的Web.config里配置相同的 sys ...
- DataURL详解--转自格桑blog
DataURI详解 Posted on 2013 年 09 月 09 日 by admin DataURI,不算新东西,却一直没用过,前些日子在webapp中用了点DataURI,就做了下相关的了解, ...
- gulp.js基础入门
安装 Node 去 nodejs.org 根据系统选择性按照教程安装Node. 创建项目 创建项目文件夹 进入项目文件夹 初始化项目 使用npm命令:npm init,根据提示完成. 安装 Gulp ...
- sql参数化查询in的参数
private Query setParameter(Query query, Map<String, Object> map) { if (map != null) { Set<S ...
- [转载]SVN-主干/分支
一个大项目在开发中可能会拆分成几个小项目,分别分去,同时共通的部分再由人做,做完后再统一合并.同时,在开发中,共通的部分修改后,其它人要保持同步. 这种情况反应到SVN的分支/合并功能上,再贴切不过了 ...
- c++程序设计之编程思想
代码块愈小,代码的功能就愈容易管理,代码的处理和移动就愈轻松. 任何一个傻瓜都能写出计算机可以理解的代码,唯有写出人类容易理解的代码,才是优秀的程序员. 绝大多数情况下,函数应该放在它所使用的数据的所 ...
- MATLAB处理信号得到频谱、相谱、功率谱
(此帖引至网络资源,仅供参考学习)第一:频谱 一.调用方法 X=FFT(x):X=FFT(x,N):x=IFFT(X);x=IFFT(X,N) 用MATLAB进行谱分析时注意: (1)函数FFT返回值 ...
- dll 劫持
库: AheadLib 输入dll 处填你要劫持的dll 路径. 例如: C:\WINDOWS\system32\lpk.dll 来自为知笔记(Wiz)
- C语言隐形密码输入
今天费了老大的劲,终于做出来了!虽然简单,但也是自己的心血,分享一下! #include<stdio.h> #include<conio.h> int main(){ char ...
- avalon使用笔记
//保存取消操作(使用双向绑定) <div ms-controller='test'> <table border="1" style="border- ...