Java实现图片的垂直方向拼接

利用Java实现了任意两张图片的垂直方向拼接,不限制大小类型,可直接用于生产。

实现任意两张图片的垂直方向拼接,对于过小图片实现了放大,保证了图片拼接后的清晰度。

对于高度大于宽度的图片,进行了-90度旋转。


import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;//垂直方向合并图片
public class ImageMerge {/*** 1比较2张图片的大小,以2张图片的最大边长为宽,以第二边长为高,构造2张空图片* 2选择第一张图片,若宽小于于高,旋转-90度,粘贴到第一张空图片上* 3选择第二张图片,若宽小于于高,旋转-90度,粘贴到第二张空图片上** @param img1 待合并的第一张图* @param img2 带合并的第二张图* @return 返回合并后的BufferedImage对象* @throws IOException*/public static BufferedImage mergeImage(BufferedImage img1, BufferedImage img2) throws IOException {//判断是否需要放大图片if (Math.max(img1.getWidth(), img1.getHeight()) > Math.max(img2.getWidth(), img2.getHeight())) {img2 = judgeIfNeedChangeImageSize(img1, img2);} else {img1 = judgeIfNeedChangeImageSize(img1, img2);}//获取背景图片宽高int w1 = img1.getWidth();int h1 = img1.getHeight();int w2 = img2.getWidth();int h2 = img2.getHeight();List<Integer> list = Arrays.asList(w1, w2, h1, h2);list.sort((v1, v2) -> v2 - v1);int maxWidth = list.get(0);int maxHeight = list.get(1);int[] backgroundImage = new int[maxWidth * maxHeight];//设置背景图片数据for (int i = 0; i < backgroundImage.length; i++) {backgroundImage[i] = -1;}//绘制背景图片BufferedImage createImage = new BufferedImage(maxWidth, maxHeight << 1, BufferedImage.TYPE_INT_RGB);createImage.setRGB(0, 0, maxWidth, maxHeight, backgroundImage, 0, maxWidth);createImage.setRGB(0, maxHeight, maxWidth, maxHeight, backgroundImage, 0, maxWidth);//准备图片一绘制数据int[] imageArrayOne = new int[w1 * h1];imageArrayOne = img1.getRGB(0, 0, w1, h1, imageArrayOne, 0, w1);if (w1 < h1) {rotateImage(w1, h1, imageArrayOne);int temp = w1;w1 = h1;h1 = temp;}//计算绘图位置,尽量居中int startX;int startY;startX = (maxWidth - w1) >> 1;startY = (maxHeight - h1) >> 1;//在背景图片上绘制图片createImage.setRGB(startX, startY, w1, h1, imageArrayOne, 0, w1);//准备图片一绘制数据int[] imageArrayTwo = new int[w2 * h2];imageArrayTwo = img2.getRGB(0, 0, w2, h2, imageArrayTwo, 0, w2);if (w2 < h2) {rotateImage(w2, h2, imageArrayTwo);int temp = w2;w2 = h2;h2 = temp;}//计算绘图位置,尽量居中startX = (maxWidth - w2) >> 1;startY = (maxHeight - h2) >> 1;//准备图片二绘制数据createImage.setRGB(startX, maxHeight + startY, w2, h2, imageArrayTwo, 0, w2);return createImage;}private static BufferedImage judgeIfNeedChangeImageSize(BufferedImage img1, BufferedImage img2) {int w1 = img1.getWidth();int h1 = img1.getHeight();int w2 = img2.getWidth();int h2 = img2.getHeight();int max1 = Math.max(w1, h1);int max2 = Math.max(w2, h2);if (max1 < max2) {return enlargementImage(img1, w1, h1, max1, max2);} else {return enlargementImage(img2, w2, h2, max2, max1);}}private static BufferedImage enlargementImage(BufferedImage srcImg, int w1, int h1, int max1, int max2) {while (max2 / max1 >= 2) {max1 *= 2;w1 *= 2;h1 *= 2;}// 放大边长BufferedImage resultImg = new BufferedImage(w1, h1, BufferedImage.TYPE_INT_RGB);//绘制放大后的图片resultImg.getGraphics().drawImage(srcImg, 0, 0, w1, h1, null);return resultImg;}/*** 旋转图片-90度** @param width  目标图像宽度* @param height 目标图像高度* @return*/public static void rotateImage(int width, int height, int[] imageArray) {int[][] arr = new int[height][width];int x = 0;int y = 0;for (int i = 0; i < imageArray.length; i++) {arr[y][x++] = imageArray[i];if (x % width == 0) {x = 0;y++;}}//旋转-90度int index = 0;for (int j = width - 1; j >= 0; j--) {for (int i = 0; i < arr.length; i++) {imageArray[index++] = arr[i][j];}}}private static final String SOURCE_FILE_PATH = "C:\\Users\\Administrator\\Pictures\\fee.jpg";private static final String WATER_FILE_PATH = "C:\\Users\\Administrator\\Pictures\\invoiceH.png";private static final String SAVE_FILE_PATH = "C:\\Users\\Administrator\\Pictures\\overlyingImageNew.jpg";/*** @param fileUrl 文件绝对路径或相对路径* @return 读取到的缓存图像* @throws IOException 路径错误或者不存在该文件时抛出IO异常*/public static BufferedImage getBufferedImage(String fileUrl)throws IOException {File f = new File(fileUrl);return ImageIO.read(f);}/*** 输出图片** @param buffImg  图像拼接叠加之后的BufferedImage对象* @param savePath 图像拼接叠加之后的保存路径*/public static void generateSaveFile(BufferedImage buffImg, String savePath) {int temp = savePath.lastIndexOf(".") + 1;try {File outFile = new File(savePath);if (!outFile.exists()) {outFile.createNewFile();}ImageIO.write(buffImg, savePath.substring(temp), outFile);System.out.println("ImageIO write...");} catch (IOException e) {e.printStackTrace();}}/*** Java 测试图片合并方法*/public static void imageMargeTest() {// 读取待合并的文件BufferedImage bi1 = null;BufferedImage bi2 = null;// 调用mergeImage方法获得合并后的图像BufferedImage destImg = null;System.out.println("下面是垂直合并的情况:");String saveFilePath = WATER_FILE_PATH;String divingPath = SOURCE_FILE_PATH;String margeImagePath = SAVE_FILE_PATH;try {bi1 = getBufferedImage(saveFilePath);bi2 = getBufferedImage(divingPath);// 调用mergeImage方法获得合并后的图像destImg = mergeImage(bi1, bi2);} catch (IOException e) {e.printStackTrace();}// 保存图像generateSaveFile(destImg, margeImagePath);System.out.println("垂直合并完毕!");}public static void main(String[] args) {// 测试图片的垂直合并imageMargeTest();}}

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

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

相关文章

Python缓存利器:cachetools库详解

Python缓存利器:cachetools库详解 1. cachetools简介2. 安装3. 基本概念3.1 LRU Cache (Least Recently Used)3.2 TTL Cache (Time-To-Live)3.3 LFU Cache (Least Frequently Used) 4. 使用示例4.1 使用LRU Cache4.2 使用TTL Cache4.3 使用LFU Cache4.4 缓存装饰器 5. 进阶用法…

Python | Leetcode Python题解之第216题组合总和III

题目&#xff1a; 题解&#xff1a; class Solution:def combinationSum3(self, k: int, n: int) -> List[List[int]]:"""回溯法&#xff0c;对于当前k和n, 枚举元素"""def backtracking(k: int, n: int, ans: List[int]):if k 0 or n <…

django学习入门系列之第四点《案例 博客案例》

文章目录 container面板案例 博客案例往期回顾 container 堆叠到两边 <div class"container-fluid clearfix"><div class"col-sm-9">1</div><div class"col-sm-3">2</div> </div>放在中间 <div clas…

Linux网络服务面试题

1、查看一个网络接口的方法有哪些&#xff1f; ①查看目录/etc/sysconfig/network-scripts/下的网卡对应的配置文件ifcfg-ens33 ②ifconfig ens33 2、如何给一个网络接口设置多个IP地址&#xff1f; 临时配置&#xff1a;ifconfig ens33:1 IP地址 netmask 掩码 up …

机器人外呼相比人工外呼优势有哪些

机器人外呼相比人工外呼的优势主要体现在以下几个方面&#xff1a; 1. 自动化与效率​ - 机器人外呼能够自动拨打大量电话&#xff0c;极大提高了工作效率。例如&#xff0c;一个机器人一天可以打上千个电话&#xff0c;相比之下&#xff0c;人工外呼的数量会有限。 - 机器人可…

算法day02 回文 罗马数字转整数

回文 搞错了String类型的indexOf方法&#xff0c;理解成获取对应下标的值&#xff0c;实际上是在找对应值的下标。 4ms 耗时最少的方法尽量不会去调用jdk提供的方法&#xff0c;而是直接使用对应的数学逻辑关系来处理&#xff0c; 甚至用 代替equals方法。 罗马数字转整数 考…

学习笔记——动态路由——OSPF工作原理(SPF算法)

3、SPF算法 SPF算法(最短路径优先算法&#xff0c;也称Dijkstra算法)由荷兰科学家狄克斯特拉于1959年提出的。 SPF算法将每一个路由器作为根(ROOT)来计算其到每一个目的地路由器的距离&#xff0c;每一个路由器根据一个统一的数据库会计算出路由域的拓扑结构图&#xff0c;该…

Go语言--函数类型、匿名函数和闭包

在Go语言中&#xff0c;函数也是一种数据类型&#xff0c;我们可以通过 type 来定义它&#xff0c;它的类型就是所有拥有相同的参数&#xff0c;相同的返回值的一种类型。 语法 通过type给函数类型起名&#xff0c;然后通过名字进行函数的调用 好处&#xff1a;多态 通过统…

python遍历目录下所有文件

python遍历目录下所有文件 方法1&#xff1a;使用os.walk()函数递归遍历目录下所有文件。方法2&#xff1a;使用os.scandir()函数遍历目录下所有文件。方法3&#xff1a;使用os.listdir()函数遍历目录下所有文件。方法4&#xff1a;使用glob模块遍历目录下所有文件。方法5&…

【大模型】大模型参数量与底层算力资源之间的关系

大模型参数量与底层算力资源之间的关系 大模型参数量与底层算力资源之间的关系引言一、大模型参数量的影响1.1 模型表达能力提升1.2 过拟合风险 二、底层算力资源的挑战2.1 计算资源需求2.2 存储与带宽瓶颈 三、估算模型所需算力资源3.1 基于参数量的估算3.2 考虑硬件效率3.3 实…

查询进程, 并且列出所在路径和端口号

ps -ef | grep port9| grep -v grep | awk {print $2} | while read pid; do # 获取启动目录 start_dir$(pwdx $pid 2>/dev/null | awk {for (i2; i<NF; i) printf "%s ", $i; print ""}) # 获取端口信息&#xff08;使用 ss 命令&#xff0…

【ssh】permission denied, please try again.

ssh执行scp操作时显示 permission denied, please try again. 1.确保被复制文件权限已开 chmod 777 file 2.如果仍未解决直接sudo sudo scp xxx xxx

信息安全驱动汽车行业快速向数字化转型

开发一款安全性良好的软件是困难的&#xff0c;它需要专业知识的积累以及对常见编程缺陷和规则的了解&#xff0c;例如检查输入范围、管理内存分配和回收、寻址字符串格式、避免悬空指针等等。通常情况下&#xff0c;编写安全代码与开发人员编写“流畅”代码的自然愿望形成了对…

【数据库】第7讲 关系数据模型(章节测验)

一. 单选题 1【单选题】下面对于关系的叙述中&#xff0c;不正确的是&#xff08;C&#xff09; A、关系中的每个属性是不可分解的B、在关系中元组的顺序是无关紧要的C、任意的一个二维表都是一个关系D、每一个关系只有一种记录类型 2【单选题】关系模型的完整性约束不包括&…

日本最新型高达式巨型机器人承担铁路维护任务

日本有制造现实生活中的高达式巨型机器人的历史&#xff0c;但它们往往是用于娱乐目的&#xff0c;而不是实际应用。不过&#xff0c;日本刚刚开始使用一个 40 英尺高的人形机器人来维护铁路线。 大约两年前&#xff0c;西日本铁路公司&#xff08;JR 西日本&#xff09;制造了…

【Unity】RPG2D龙城纷争(八)寻路系统

更新日期&#xff1a;2024年7月4日。 项目源码&#xff1a;第五章发布&#xff08;正式开始游戏逻辑的章节&#xff09; 索引 简介一、寻路系统二、寻路规则&#xff08;角色移动&#xff09;三、寻路规则&#xff08;角色攻击&#xff09;四、角色移动寻路1.自定义寻路规则2.寻…

[C++]——同步异步日志系统(2)

同步异步日志系统 一、 不定参函数1.1 不定参宏函数的使用1.2 C 语言中不定参函数的使用1.3 C不定参数使用 二、设计模式2.1 单列模式2.2 工厂模式2.3 建造者模式2.4 代理模式 在我们开发同步异步日志系统之前&#xff0c;需要了解一些相关的技术知识。 一、 不定参函数 在初学…

从键盘输入一个3位数字字符串,将其转换为数字,并逆序,不允许使用切片,不需要做判断

分析思路&#xff1a; 首先&#xff0c;从键盘输入一个字符串类型的三位数字&#xff0c;使用input()函数获取用户的输入。 使用int()函数将输入的字符串转换为整数类型。 将输入的整数进行逆序操作&#xff0c;其中具体的步骤包括通过除法和取余操作获取个位、十位和百位上的…

VCL界面组件DevExpress VCL v24.1 - 发布全新的矢量主题

DevExpress VCL是DevExpress公司旗下最老牌的用户界面套包&#xff0c;所包含的控件有&#xff1a;数据录入、图表、数据分析、导航、布局等。该控件能帮助您创建优异的用户体验&#xff0c;提供高影响力的业务解决方案&#xff0c;并利用您现有的VCL技能为未来构建下一代应用程…

DP学习——策略模式

学而时习之&#xff0c;温故而知新。 敌人出招&#xff08;使用场景&#xff09; 业务中需要多个算法可替换&#xff0c;而不能重构代码时&#xff0c;怎么办&#xff1f;这个时候就要出策略模式这一招了。 具体招式 策略模式的招式&#xff0c;就是把需要替换的算法抽象成…