图片缩放应用(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不仅能滚动显示大量内容,还能对其内容进行缩放处理 也就是说,要完成缩放功能的话,只 ...
随机推荐
- Python体验(08)-图形界面之工具栏和状态栏
# coding=utf-8 import wx # 导入必须的Python包 class MenuForm(wx.Frame): def OnQuit(self,event): self.Close ...
- 从 A/Looper: Could not create epoll instance. errno=24 错误浅谈解决各种 bug 的思路
今天代码写着写着就莫名闪退了,手机也没有“程序停止运行”的提示,logcat也没有看到蓝色的调用栈log,这样的闪退最是蛋疼了,还好必现.复现几次之后,终于从logcat中看到了一行可疑的log: A ...
- css3动画(@keyframes和animation的用法)
animation基本用法是: animation: name keeping-time animate-function delay times iteration final; 第一个参数:nam ...
- python转exe的小工具
其实只是在cxfreeze的基础上加了个壳,做成窗口软件了 使用了pyqt做的界面,软件发布在了开源中国上,可以直接去下面的地址查看 http://git.oschina.net/robocky/py ...
- maven基本用法
一.下载及安装 1.1 下载maven 3.1.1 先到官网http://maven.apache.org/download.cgi 下载最新版本(目前是3.1.1 ),下载完成后,解压到某个目录(本 ...
- c++ 类的静态变量
类的静态变量作为类的一部分,但不由类的创建产生,类的销毁而消失.静态变量和全局变量一样,会在main函数结束后销毁. 类可以对静态变量的值进行改变 #pragma once class ctest { ...
- ReactJS学习笔记(一)
1.依赖的资源: <script type="text/javascript" src='../asset/react.js'></script> &l ...
- 简单配置webpack自动刷新浏览器
文档地址 http://webpack.github.io/docs/usage.html 首先全局安装webpack(我这里使用的是淘宝的cnpm) cnpm install webpack 检查 ...
- HTML的FormData对象
FormData是HTML5标准制定的一个新的封装对象,有了FormData对象,可以方便地通过javascript创建表单数据,直接以ajax发送到服务器中. 目前浏览器的支持情况为: 详细的介绍与 ...
- 关于JDK 安装,以及Java环境的设置
关于JDK 安装,以及Java环境的设置 1.下载JDK1.6,选择对应的安装路径 2.配置相应的Java 环境变量 A.属性名称:JAVA_HOME 属性值:C:\Program Files\Jav ...