前言:在开发程序时,可能需要将一张照片或影像显示在程序内部界面上。一般来说,界面的大小是固定的,不超过屏幕大小,但是我们需要显示的照片往往有不同的分辨率,并且一张照片的像素动不动就上千万,即使1920*1080的屏幕最多也只能显示200万像素的照片。要想在程序界面上浏览整张图像,必然需要加入缩放和平移功能。缩放使得我们能够以较原图更低的分辨率加载并显示整张图像,平移使得在较大分辨率尺度下界面只能加载影像部分区域时方面我们浏览影像的其他部分。参考目前已有的各类图像浏览软件,提出一种实现方案。

简介:采用平面坐标系统一图像坐标和显示窗口(界面)坐标。当图像加载时,界面与图像计算缩放比例,界面上每个像素按照缩放比例生成坐标位置,然后根据坐标位置对原图进行采样并生成一张与界面大小完全一样的影像,之后界面直接显示该图像即可。完成图像加载后,界面上显示的是原图根据窗口大小按比例缩放后的全貌。接下来,只需要改变缩放比例即可实现缩放,增大缩放比例相当于界面无形中增大了尺寸,原图看起来在界面中变得更小,而减小缩放比例,相当于界面变小了,界面只能框下原图更小范围。平移则是通过改变界面中心坐标实现,由于加载图像时,界面中心坐标初始值与图像中心坐标一致,当改变界面中心坐标,通过界面中心坐标和窗口大小从带坐标的原图中进行采样即可获取平移后的影像。

接下来对上述方案进行详细描述。

第一步:读取图像,获取图像的宽和高以及色彩信息,其实图像本身就是一个二维平面坐标系统,(0,0)对应一个RGB色彩值,(0,1)又对应另一个RGB色彩值。如果想要获取某一区域的像素数据,只需要根据这个坐标值加上需要获取的宽度和高度参数即可,图像裁剪也是同样原理。那么现在就可以根据图像宽和高建立一个坐标系,以图像左下角为坐标系原点。图像中心坐标为image_center=(image_width/2,image_height/2)。此时还有一个重要步骤就是设定步长,也就是每个像素在坐标系中的跨度范围,由于已经将图像中心坐标设定为(image_width/2,image_height/2),那么一个像素跨度为1,image_step=1。此时原始图像已经有了固定的坐标,它的每个像素在坐标系中的位置就固定了,坐标系中有图像的位置就有了对应的RGB值,图像范围以外的位置可以设定为黑色或其他颜色对应的RGB值。

概念图:

第二步:将在界面中全局显示图像。首先获取界面宽和高,window_width,window_height。接下来,计算缩放比例:width_scale=window_width/image_width,height_scale=window_height/image_height。由于要保持图像宽高比,必须比较width_scale和height_scale,选取较小的一个作为缩放比例scale。接着计算界面上每个像素在全局显示下对应的步长,window_step=image_step/scale。由于图像全局显示,界面的中心和图像中心一致,即window_center=image_center。接下来根据界面已经确定的参数(window_width,window_height,window_step,window_center),从坐标系中寻找界面每个像素对应的RGB值。由于界面宽高比和图像宽高比不保证一致,图像全局加载后肯定是存在一些空白的地方。

概念图:

实际效果:

第三步:放大和缩小。有前面两步的实现,已经为放大缩小打好了基础。第二步为了在界面全局显示图像,相当于已经进行了一次缩放。图像上每一个像素的坐标都是固定的,界面中心坐标与图像中心坐标一致,我们只需要改变界面上每个像素在坐标系中的步长即可。当window_step值增加,也就是整个界面在坐标系中范围增大,界面边界随着window_step增大将远远超出图像范围,图像在界面中占的面积也就变小,也就实现了将图像缩小显示,随着不断缩小,最终图像只会在界面中占一个像素。反之,window_step值减小,整个界面在坐标系中范围也就减小,界面边界将小于图像范围,显示的将是图像的部分区域,随着不断放大,界面最终只会显示图像中某一个像素的RGB值。

缩小操作概念图:

缩小效果:

放大操作概念图:

放大效果图:

第四步:平移的实现。其实将图像和界面统一在一个坐标系内本身就是为了同时解决缩放和平移问题的。本质上讲,缩放并没有对图像进行任何缩小或放大操作,是界面投影到坐标系中的大小在发生变化。界面在坐标系中的投影大小可以解决图像缩放问题,那么界面中心在坐标系中的投影位置也就解决了图像的平移问题。当我们改变window_center,不改变window_step,由于界面的宽和高是固定的,整个界面在坐标系中进行移动,那么获取到的图像就是移动图像产生的效果。

平移操作概念图:

移动效果图:

总结:到此为止,图像浏览界面的缩放和平移实现就完成了。该方案的核心思想就是给原图每一个像素赋予一个固定坐标,在界面中进行缩放和平移,变化的是界面在坐标系中投影的位置和大小,图像本身是没有进行任何操作的。通过调整界面大小和位置,从坐标系中去采样色彩信息,返回一张图像,由于界面的像素是固定的,每次采样只采样与界面分辨率一样的数据量,计算量相对较小,基本可以实时更新画面。如果界面窗口大小是1000*1000像素,那么总像素是100万,每次缩放或平移操作需要更新100万像素的数据量,如果电脑配置较差,可能会有些许卡顿。

补充:利用鼠标来实现图像的缩放和平移。一般图像浏览软件都会加入鼠标事件监听来实现图像的缩放和平移。这里我采用鼠标滚轮来实现图像缩放,鼠标左键拖动来实现图像平移。可以定义当滚轮向前滚动来放大图像,滚轮每向前滚动一个单位,window_step/1.1,由于我们是缩放界面在坐标系中的大小,不是缩放图像,当界面的步长减小,对应在坐标系中的大小也就是变小,能够采样到的图像范围也就变小,实现了图像的放大,与图像放大是反的,因为图像本身没有变化。当然,如果想要缩小图像显示,加大界面步长,window_step*1.1,那么采样到的图像范围就更大,图像在界面中是缩小了的。这里的1.1作为缩放参数是可以更改的。图像的平移采用鼠标左键拖动,当按下鼠标左键,记录下当前鼠标在界面上的位置,这个位置包含两个参数X和Y,当鼠标开始拖动,获取每次拖动后的位置,减去上一次的位置,结合界面当前步长window_step和XY方向上的平移量便获得了界面中心坐标在坐标系中需要移动的位置,再根据这个位置重新采样图像并更新到界面上。

图像浏览界面缩放和平移操作的实现相关推荐

  1. Mapxtreme Java 地图缩放,平移操作的原理和实现

    2019独角兽企业重金招聘Python工程师标准>>> 要想实现Mapxtreme Java 地图的缩放,平移操作,那么必须了解下Mapj这个对象,这个是官方文档对MapJ的名词解释 ...

  2. opencv 图像仿射变换 计算仿射变换后对应特征点的新坐标 图像旋转、缩放、平移...

    常常需要最图像进行仿射变换,仿射变换后,我们可能需要将原来图像中的特征点坐标进行重新计算,获得原来图像中例如眼睛瞳孔坐标的新的位置,用于在新得到图像中继续利用瞳孔位置坐标. 仿射变换在:http:// ...

  3. python dicom放大_python3实现对dicom图像处理(图像呈现,缩放,平移)

    dicom图像处理 DICOM(Digital Imaging and Communications in Medicine)即医学数字成像和通信.DICOM被广泛应用于放射医疗,心血管成像以及放射诊 ...

  4. C#实现平面图形图像缩放、平移、自定义坐标系

    2022.9.13 将本程序封装成了控件 "熊猫视图".Net图形控件功能介绍 2022.7.6 完成了以任意鼠标位置为中心的鼠标滚轮缩放功能. 2022.3.1 去年进行了1年的 ...

  5. Android单点触控技术,对图片进行平移,缩放,旋转操作

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/42833893),请尊重他人的辛勤劳动成果,谢谢! 相信大家 ...

  6. 基于 MFC+Halcon 实现图像缩放、平移

    1.前言 在机器视觉系统中,图像处理是必不可少的一环.其中设置图像ROI(Region of interest)是基本操作,例如在模板匹配.直线拟合.圆拟合等功能中均会用到.当MFC对话框中的图片控件 ...

  7. 【J2me3D系列学习文章之三】(立即模式)对立方体进行变换操作-旋转、缩放、平移...

     本文源地址:http://blog.csdn.net/xiaominghimi/archive/2010/12/09/6064367.aspx  Himi  原创, 转载请注明! 谢谢. 上一篇文章 ...

  8. MFC+Halcon 真正实现图像缩放、平移

    网上看了几个MFC+Halcon对图像进行缩放.平移,发现很多是不完整或者没有真正实现这2个功能,所以自己去真正实现 实现平台:VS2010+HALCON18.11. 主要知识点: 1.halcon与 ...

  9. OpenCasCade学习笔记(三):加载显示STEP格式图片,并实现平移、缩放和旋转操作

    OpenCasCade学习笔记(三):加载显示STEP格式图片,并实现平移.缩放和旋转操作 C3DWidget.h #pragma once#include <QtWidgets/QApplic ...

最新文章

  1. 啥?修改下 URL 就能高速下载网盘资源和百度文库?
  2. 数学符号正三角形△和倒三角形▽的意思
  3. python获取用户输入的数字_Python 将用户输入的数字 提取整数谢谢
  4. 【架构】学习余额宝背后的服务治理架构
  5. brew php mysql_MAC下用homebrew安装及配置apache、php和mysql
  6. java构建内存池队列_内存池完整实现代码及一些思考
  7. java 蓝桥杯算法训练 瓷砖铺放(题解)
  8. LeetCode(905)——按奇偶排序数组(JavaScript)
  9. 制作Win10PE启动盘
  10. mac安装软件提示不被信任的程序
  11. 给定一个递增序列,a1 a2 ...an 。定义这个序列的最大间隔为d=max{ai+1 - ai }(1≤in),现在要从a2 ,a3 ..an-1 中删除一个元素。问剩余序列的最大间隔最小...
  12. CAD中的标注文字如何沿弧线排列?
  13. 批量添加联系人的方法
  14. 微信小程序的路由,以及生命周期
  15. osgEarth的Rex引擎原理分析(七十三)从高程文件读取的高程信息如何填充rex的高程瓦片
  16. Intel Realsense D435i标定详细步骤
  17. 关于手机的挑选的精品帖子
  18. Uncaught TypeError: Cannot read properties of undefined (reading ‘0‘)
  19. Linux kernel oops
  20. 中国台湾内存制造商威刚遭勒索攻击

热门文章

  1. 同步规则和happen-before规则
  2. Python程序开发——第一章 基本python语法
  3. Web前端开发笔记——第二章 HTML语言 第七节 表格标签
  4. oracle转成整型_Oracle中如何用SQL把字符串转换成整型
  5. Web服务-Nginx网页服务
  6. Linux服务器硬件及RAID配置(操作实验详细图解)
  7. 均匀白噪声的定义及特点_噪声的物理本质是什么?
  8. 网站api自己怎么写_网站描述怎么写?对网站优化有什么作用?
  9. layui js添加html,layui.js如何声明全局变量?
  10. activepython win32com_activepython下载