DevC++ easyx 从图片放缩理解双线性插值意义

很久就想实现的一个功能,图片能够拖动,图片能够通过视口局部显示,但是图片放大缩小还是解决。

于是心心念念半年过去了。

恰逢校园地图大作业,按意思来说是可视化,想着能不能改改代码,搓一个地图,然后实现放大缩小。

功夫不负有心人

找到上古传说,感谢大哥:

【图像缩放】基于双线性插值算法的图像缩放函数_easyx吧_百度贴吧 (baidu.com)

 但是只有纯粹的算法和一个函数,需要更好适配鼠标滚轮的话,还得现找,就又尝试找鼠标滚轮,翻出来代码,原来easyx图形库还是内置了这个的。

如何用鼠标滚轮实现绘图窗口的缩放呢 - CodeBus

然后去了解大哥用的处理图像的算法,但是现在还是一点也不明白,只能说是图片像素是固定的屏幕的像素只能是0.02毫秒长宽,但是图片放大,原来的一个像素就能表示的图片,现在需要四个像素来表示,那么像素要怎么选择颜色。

另一个是缩小,原来一个像素点了,但是图片缩小了,一个像素顶原来的四个像素,如何确定这个像素的颜色,同样也是问题。

而插值法,简单来说,就是在两个数据中间猜一个数据。这样描述起来就是无中生有了一个新像素。对应放大。

另一种缩小,两个数据中间猜一个,去替换这两个数据中间的一堆数据,以一当百。对应缩小。

目前理解程度就是这样。

至于双线性,就是x方向补上像素,对应x方向拉伸,拉伸完,再往y方向拉伸,补充像素。

而这样的结果却是x会插值两次,然后y插值一次。如下面链接的图。

后来瞪图才明白,x插值其实是形成了矩形,y需要确定一个区间,这样才能在矩形的中心插入像素。替代去整个矩形。这样面积就缩小了,整个矩形的信息就拿中心插值产生的像素代替了。

这样原图有多少个矩形,新图就有多少个像素。正好信息一一对应,一个矩形丢失其他像素的信息,拿中心插值产生的像素代替矩形。

详解理解自:

图像处理+双线性插值法_双线性插值计算任意位置处的灰度值-CSDN博客

 不多说,上代码。

#include <graphics.h>
#include <iostream>
#include <graphics.h>
#include <conio.h>
//#include"BIA_ZoomImage.h"void ZoomImage(IMAGE* P,IMAGE* Q,double ZoomRate,bool HighQuality=false,double ZoomRate2=0) {//不填写第二缩放参数则默认和第一相等if(ZoomRate2==0)ZoomRate2=ZoomRate;//根据缩放比率设定目标图像大小P->Resize((int)(Q->getwidth()*ZoomRate),(int)(Q->getheight()*ZoomRate2));//分别对原图像和目标图像获取指针DWORD* M=GetImageBuffer(P);DWORD* N=GetImageBuffer(Q);//选择高质量则使用双线性插值算法if(HighQuality) {for(int i=0; i<P->getheight(); i++) {for(int j=0; j<P->getwidth(); j++) {//求出目标图像对应像素点在原图的浮点坐标并取整int X_=(int)((j+0.5)/ZoomRate-0.5);int Y_=(int)((i+0.5)/ZoomRate2-0.5);//根据取整坐标求A1(X,Y), A2(X+1,Y), A3(X,Y+1), A4(X+1,Y+1)即浮点坐标临近4个点的颜色平均值。M[j+i*P->getwidth()]=RGB((GetRValue(N[X_+Y_*Q->getwidth()])+GetRValue(N[(X_+1)+Y_*Q->getwidth()])+GetRValue(N[X_+(Y_+1)*Q->getwidth()])+GetRValue(N[(X_+1)+(Y_+1)*Q->getwidth()]))/4,(GetGValue(N[X_+Y_*Q->getwidth()])+GetGValue(N[(X_+1)+Y_*Q->getwidth()])+GetGValue(N[X_+(Y_+1)*Q->getwidth()])+GetGValue(N[(X_+1)+(Y_+1)*Q->getwidth()]))/4,(GetBValue(N[X_+Y_*Q->getwidth()])+GetBValue(N[(X_+1)+Y_*Q->getwidth()])+GetBValue(N[X_+(Y_+1)*Q->getwidth()])+GetBValue(N[(X_+1)+(Y_+1)*Q->getwidth()]))/4);}}} else//选择低质量则按常规方法缩放{for(int i=0; i<P->getheight(); i++)for(int j=0; j<P->getwidth(); j++)//根据目标图像像素点位置逆推算原图像像素点赋值M[j+i*P->getwidth()]=N[(int)(j/ZoomRate)+(int)(i/ZoomRate2)*Q->getwidth()];}
}int main() {initgraph(1640, 1480);IMAGE p(1200,1000);IMAGE b(500,400);cleardevice();SetWorkingImage(&p);setbkcolor(BLUE);cleardevice();circle(320, 240, 100);ZoomImage(&b,&p,0.9,0,0);
//	把p放缩到b里面,0.9小于1,所以是缩小了的p。SetWorkingImage();putimage(0,0,&b);ExMessage msg;double t=1;while(1) {
//	m=getmessage();if (peekmessage(&msg, EM_MOUSE)) {if (msg.message == WM_MOUSEWHEEL) {
//				鼠标滚轮滚动的话 if (msg.wheel > 0) {t+=0.1;
//					放大} else {t-=0.1;
//					缩小}ZoomImage(&b,&p,t,0,0);SetWorkingImage();setbkcolor(BLACK);cleardevice();putimage(0,0,&b);fillrectangle(300,600,500,800);}}}getch();closegraph();return 0;
}

贴吧上古传说,代码自大哥的百度网盘而来。

【图像缩放】基于双线性插值算法的图像缩放函数_easyx吧_百度贴吧 (baidu.com) 

#ifndef ZOOM_H
#define ZOOM_Hvoid ZoomImage(IMAGE* P,IMAGE* Q,double ZoomRate,bool HighQuality=false,double ZoomRate2=0)
{//不填写第二缩放参数则默认和第一相等if(ZoomRate2==0)ZoomRate2=ZoomRate;//根据缩放比率设定目标图像大小P->Resize((int)(Q->getwidth()*ZoomRate),(int)(Q->getheight()*ZoomRate2));//分别对原图像和目标图像获取指针DWORD* M=GetImageBuffer(P);DWORD* N=GetImageBuffer(Q);//选择高质量则使用双线性插值算法if(HighQuality){for(int i=0;i<P->getheight();i++){for(int j=0;j<P->getwidth();j++){//求出目标图像对应像素点在原图的浮点坐标并取整int X_=(int)((j+0.5)/ZoomRate-0.5);int Y_=(int)((i+0.5)/ZoomRate2-0.5);//根据取整坐标求A1(X,Y), A2(X+1,Y), A3(X,Y+1), A4(X+1,Y+1)即浮点坐标临近4个点的颜色平均值。M[j+i*P->getwidth()]=RGB((GetRValue(N[X_+Y_*Q->getwidth()])+GetRValue(N[(X_+1)+Y_*Q->getwidth()])+GetRValue(N[X_+(Y_+1)*Q->getwidth()])+GetRValue(N[(X_+1)+(Y_+1)*Q->getwidth()]))/4,(GetGValue(N[X_+Y_*Q->getwidth()])+GetGValue(N[(X_+1)+Y_*Q->getwidth()])+GetGValue(N[X_+(Y_+1)*Q->getwidth()])+GetGValue(N[(X_+1)+(Y_+1)*Q->getwidth()]))/4,(GetBValue(N[X_+Y_*Q->getwidth()])+GetBValue(N[(X_+1)+Y_*Q->getwidth()])+GetBValue(N[X_+(Y_+1)*Q->getwidth()])+GetBValue(N[(X_+1)+(Y_+1)*Q->getwidth()]))/4);}}}else//选择低质量则按常规方法缩放{for(int i=0;i<P->getheight();i++)for(int j=0;j<P->getwidth();j++)//根据目标图像像素点位置逆推算原图像像素点赋值M[j+i*P->getwidth()]=N[(int)(j/ZoomRate)+(int)(i/ZoomRate2)*Q->getwidth()];}
}#endif

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/581000.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flutter配置Android和IOS允许http访问

默认情况下&#xff0c;Android和IOS只支持对https的访问&#xff0c;如果需要访问不安全的连接&#xff0c;也就是http&#xff0c;需要做以下配置。 Android 在res目录下的xml目录中(如果不存在&#xff0c;先创建xml目录)&#xff0c;创建一个xml文件network_security_con…

Appium+python自动化(三)- SDK Manager(超详解)

简介 本来宏哥一开始打算用真机做的&#xff0c;所以在前边搭建环境时候就没有下载SDK&#xff0c;但是由于许多小伙伴通过博客发短消息给宏哥留言说是没有真机&#xff0c;所以顺应民意整理一下模拟器&#xff0c;毕竟“得民心者&#xff0c;得天下”。SDK顾名思义&#xff0c…

【Linux学习笔记】Linux下nginx环境搭建

1、下载nginx 安装rpm命令: rpm ivh nginx-release.rpm。(直接使用linux命令下载wget http://nginx.org/packages/rhel/6/noarch/RPMS/nginx-release-rhel-6-0.el6.ngx.noarch.rpm 2、设置nginx开机启动 chkconfig nginx on 3、开启nginx服务 方法一&#xff1a;service nginx…

引力魔方的基础知识总结

1.简介&#xff1a;引力魔方是投放推荐广告的渠道&#xff0c;融合了钻展和超推&#xff1b;更新升级平台之后统一叫做人群精准推广&#xff1b; 2.展位&#xff1a;包括淘宝首页、内页频道页、门户、帮派、画报等多个淘宝站内广告位 &#xff0c;每天拥有超过8亿的展现量&…

统一身份认证,构建数字时代的安全壁垒——统一身份认证介绍、原理和实现方法

前言 随着数字化时代的来临&#xff0c;个人和机构在互联网上的活动越来越频繁&#xff0c;对于身份认证的需求也愈发迫切。为了有效应对身份欺诈、数据泄露等问题&#xff0c;统一身份认证&#xff08;Unified Identity Authentication&#xff09;应运而生。 在本文博主将介…

快速排序:高效分割与递归,排序领域的王者算法

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《数据结构&算法》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! &#x1f4cb; 前言 快速排序这个名词&#xff0c;快排之所以叫快排肯定是有点东西的。他在处理大规模数据集时表现及其…

MySQL数据库编译及安装

将安装mysql 所需软件包传到/opt目录下 cd /opt mysql-5.7.20.tar.gz boost_1_59_0.tar.gz #支持c的运行库 安装环境依赖包 yum -y install \ gcc \ gcc-c \ ncurses \ #字符终端下图形互动功能的动态库 ncurses-devel \ #ncurses开发包 bison \ #语法分析器 cmake #mysql需…

怎么设置Facebook双重验证,让Facebook账号更稳定?

对于跨境电商而言&#xff0c;Facebook 账号被封是常有的事&#xff0c;原因之一可能是没有给 Facebook 设置双重验证&#xff0c;今天就和大家科普一下什么是 Facebook双重验证以及如何设置&#xff0c;另外&#xff0c;作为跨境卖家&#xff0c;我们还需要了解如何保护 Faceb…

Bert-vits2最终版Bert-vits2-2.3云端训练和推理(Colab免费GPU算力平台)

对于深度学习初学者来说&#xff0c;JupyterNoteBook的脚本运行形式显然更加友好&#xff0c;依托Python语言的跨平台特性&#xff0c;JupyterNoteBook既可以在本地线下环境运行&#xff0c;也可以在线上服务器上运行。GoogleColab作为免费GPU算力平台的执牛耳者&#xff0c;更…

视频格式网络地址转换视频到本地,获取封面、时长,其他格式转换成mp4

使用ffmpeg软件转换网络视频&#xff0c;先从官网下载对应操作系统环境的包 注意:网络地址需要是视频格式结尾&#xff0c;例如.mp4,.flv 等 官网地址&#xff1a;Download FFmpeg window包&#xff1a; linux包&#xff1a; 如果下载缓慢&#xff0c;下载迅雷安装使用…

Pycharm2023版本:Python远程调试配置详解

工欲善其事&#xff0c;必先利其器 首先你需要选择一个专业版本的pycharm&#xff0c;社区版本不支持远程配置功能&#xff0c;专业版下载地址&#xff1a;Pycharm 2023 双击程序进行安装&#xff0c;30天内免费试用&#xff0c;如果想要永久使用&#xff0c;办法你懂的&…

GBASE南大通用 GCDW阿里云计算巢:自动化部署云原生数据仓库

目前&#xff0c;GBASE南大通用已与阿里云计算巢合作&#xff0c;双方融合各自技术优势&#xff0c;助力企业用户实现云上数据仓库的自动化部署&#xff0c;让用户在云端获取数据仓库服务“更简单”&#xff0c;让用户在云端使用数据仓库服务“更便捷”&#xff0c;满足企业用户…

Arm CCA机密计算扩展

目录 Realms Realm World和Root World Arm TrustZone扩展和Arm RME之间有什么区别? 在《什么是机密计算?》中所述,Arm CCA允许您在阻止更高特权软件实体(例如Hypervisor)访问的同时部署应用程序或虚拟机(VM)。然而,通常由这些特权软件实体管理内存等资源。在这种情况…

在Visual Studio(VS)编译器中,Release和Debug区别

一、 优化级别 1、Debug&#xff08;调试&#xff09; 在Debug模式下&#xff0c;编译器不会对代码进行优化&#xff0c;而是专注于生成易于调试的代码。这使得开发者可以在调试过程中更直观地跟踪变量的值和程序的执行流程。 2、Release&#xff08;发布&#xff09; 在Relea…

CSS3——动画

动画 什么是帧 一段动画&#xff0c;就是一段时间内连续播放n个画面。每一张画面&#xff0c;我们管它叫做“帧”。一定时间内连续快速播放若干个顿&#xff0c;就成了人眼中所看到的动画。同样时间内&#xff0c;播放的帧数越多&#xff0c;画面看起来越流畅。 2.什么是关键…

uniapp 安卓模拟器链接

下载genymotion 安装 配置adb路径 模拟端口设为 5307

数据库系统课程设计(高校成绩管理数据库系统的设计与实现)

目录 1、需求分析 1 1.1 数据需求描述 1 1.2 系统功能需求 3 1.3 其他性能需求 4 2、概念结构设计 4 2.1 局部E-R图 4 2.2 全局E-R图 5 2.3 优化E-R图 6 3、逻辑结构设计 6 3.1 关系模式设计 6 3.2 数据类型定义 6 3.3 关系模式的优化 8 4、物理结构设计 9 4.1 聚…

CSDN规则详解——csdn那些你不知道的事儿(点赞、评论、收藏)

文章目录 每日一句正能量前言点赞评论收藏原力等级和博客等级后记 每日一句正能量 “只有奋斗者才能成为胜利者&#xff0c;只有坚持者才能创造奇迹。” - 迈克尔乔丹 这句话来自于世界著名篮球运动员迈克尔乔丹&#xff0c;他以无与伦比的天赋和努力成为了篮球界的传奇人物。他…

基于ChatGpt,Java,SpringBoot,Vue,Milvus向量数据库的定制化聊天Web demo

customized chat GitHub - bigcyy/customized-chatgpt: 基于ChatGpt&#xff0c;Java&#xff0c;SpringBoot&#xff0c;Vue&#xff0c;Milvus向量数据库的定制化聊天Web demo 简介 基于ChatGpt&#xff0c;Java&#xff0c;SpringBoot&#xff0c;Vue&#xff0c;Milvus向…

模式识别与机器学习-SVM(线性支持向量机)

线性支持向量机 线性支持向量机间隔距离学习的对偶算法算法:线性可分支持向量机学习算法线性可分支持向量机例子 谨以此博客作为复习期间的记录 线性支持向量机 在以上四条线中&#xff0c;都可以作为分割平面&#xff0c;误差率也都为0。但是那个分割平面效果更好呢&#xff1…