Java图片拼接

最近遇到一个挺离谱的功能,某个表单只让上传一张图,多图上传会使导出失败。跟开发沟通后表示,这个问题处理不了。我...

遂自己思考,能否以曲线救国的方式拯救一下,即不伤及代码之根本,又能解决燃眉之急。灵光一闪,想到了美图救救的图片拼接功能。于是就想着尝试一下是否可行。

考虑到图片拼接界限等,目标实现:白色图片背景(默认是黑色),以最大图片的宽为最终拼接图片的宽,图片纵向拼接,图与图之间间隔35px。代码如下(异常捕获、空值判断、权限判断等需自行完善):

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;@RestController
public class ImagePinJie {@PostMapping("/imgPinJie")public String imageUpload(@RequestParam("files") MultipartFile[] files) throws IOException {if (files.length == 0) {return "没有文件被上传";}List<BufferedImage> bufferedImages = new ArrayList<>();List<Integer> widths = new ArrayList<>();List<Integer> heights = new ArrayList<>();for (MultipartFile file : files) {if (!file.isEmpty()) {try {BufferedImage bi = ImageIO.read(file.getInputStream());bufferedImages.add(bi);widths.add(bi.getWidth());heights.add(bi.getHeight());} catch (Exception e) {return "上传失败: " + e.getMessage();}}}BufferedImage bufferedImage = imgPinJie(bufferedImages, widths, heights);createImage(bufferedImage);return "上传成功";}public BufferedImage imgPinJie(List<BufferedImage> bufferedImages, List<Integer> widths, List<Integer> heights) {int maxWidth = widths.stream().mapToInt(Integer::intValue).max().getAsInt();int totalHeight = heights.stream().mapToInt(Integer::intValue).sum() + (heights.size() - 1) * 35;BufferedImage bufferedImage = new BufferedImage(maxWidth, totalHeight, BufferedImage.TYPE_INT_RGB);int offset = 0;Graphics2D graphics = bufferedImage.createGraphics();graphics.setColor(Color.WHITE);graphics.fillRect(0, 0, maxWidth, totalHeight);for(BufferedImage bi : bufferedImages) {graphics.drawImage(bi, 0, offset, bi.getWidth(), bi.getHeight(), null);offset += bi.getHeight() + 35;}graphics.dispose();return bufferedImage;}public void createImage(BufferedImage bufferedImage) throws IOException {File file = new File("C:/Users/iTcys/Pictures/pinjie.png");ImageIO.write(bufferedImage, "png", file);}
}

接口测试

最终效果

至此,图片拼接完成了,接下来准备研究一下前端拼接的方式。

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

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

相关文章

webGL硬核知识:图形渲染管渲染流程,各个阶段对应的API调用方式

一、图形渲染管线基础流程概述 WebGL 的图形渲染管线大致可分为以下几个主要阶段&#xff0c;每个阶段都有其特定的任务&#xff0c;协同工作将 3D 场景中的物体最终转换为屏幕上呈现的 2D 图像&#xff1a; 顶点处理&#xff08;Vertex Processing&#xff09;阶段&#xff1…

大数据面试题--企业面试真题

大数据面试题--企业面试真题 PlanHub 点击访问获取&#xff1a; 大数据面试体系专栏_酷兜科技​www.kudoumh.top/hlwai/85.html 点击访问获取&#xff1a; 大数据面试体系专栏_酷兜科技​www.kudoumh.top/hlwai/85.html 大数据面试题汇总 HDFS 1、 HDFS 读写流程。 2、HDF…

lambda初探(一)

发生捕获时&#xff0c;拿到x,y的值 退出lambda表达式后&#xff0c;foo外层的值不变化。foo内部的x&#xff0c;值是持续的&#xff0c;像static。即使退出foo函数后&#xff0c;值的状态依然保持。 外层x的值变化&#xff0c;并不影响foo内部。 foo运行了两次&#xff0c;内…

【D3.js in Action 3 精译_046】DIY 实战:在 Observable 平台利用饼图布局函数实现 D3 多个环形图的绘制

当前内容所在位置&#xff1a; 第五章 饼图布局与堆叠布局 ✔️ 5.1 饼图和环形图的创建 ✔️ 5.1.1 准备阶段&#xff08;一&#xff09;5.1.2 饼图布局生成器&#xff08;二&#xff09;5.1.3 圆弧的绘制&#xff08;三&#xff09;5.1.4 数据标签的添加&#xff08;四&#…

基于Spring Boot的智慧农业专家远程指导系统

一、系统背景与意义 随着科技的不断进步&#xff0c;农业领域也在积极寻求创新与发展。然而&#xff0c;传统农业生产中农民往往依靠经验进行种植和养殖&#xff0c;缺乏科学的指导和技术支持。同时&#xff0c;农业专家资源有限&#xff0c;难以覆盖广大的农村地区&#xff0…

【JavaEE初阶】线程 和 thread

本节⽬标 认识多线程 掌握多线程程序的编写 掌握多线程的状态 一. 认识线程&#xff08;Thread&#xff09; 1概念 1) 线程是什么 ⼀个线程就是⼀个 "执⾏流". 每个线程之间都可以按照顺序执⾏⾃⼰的代码. 多个线程之间 "同时" 执⾏着多份代码. 还…

练习题 最小栈

最小栈 最小栈 class MinStack {private Stack<Integer> stack;private Stack<Integer> minstack;public MinStack() {stacknew Stack<>();minstacknew Stack<>();}public void push(int val) {stack.push(val);if(minstack.empty()){minstack.push(…

全志H618 Android12修改doucmentsui鼠标单击图片、文件夹选中区域

背景: 由于当前的文件管理器在我们的产品定义当中,某些界面有改动的需求,所以需要在Android12 rom中进行定制以符合当前产品定义。 需求: 在进入File文件管理器后,鼠标左击整个图片、整个文件夹可以选中该类型,进行操作,故代码分析以及客制化如下: 主要涉及的代码:…

堆【Lecode_HOT100】

文章目录 1.数组中的第&#xff2b;个最大元素No.2152.前K个高频元素347 1.数组中的第&#xff2b;个最大元素No.215 方法一&#xff1a;NlogN不能满足时间复杂度的要求 public int findKthLargest(int[] nums, int k) {Arrays.sort(nums);return nums[nums.length-k];}方法二&…

Android 搭建AIDL Client和Server端,双向通信

一、背景 使用AIDL,搭建Client和Server端,实现跨进程通讯,即两个应用之间可以相互通讯。这里列举AIDL实现的方式和需注意的细节&#xff0c;并附上源码。 二、实现方式 2.1 定义AIDL需要的接口,名字为xxx.aidl,Client和Server端 AIDL接口的包名和aidl文件必须一致&#xff0c…

HIPT论文阅读

题目《Scaling Vision Transformers to Gigapixel Images via Hierarchical Self-Supervised Learning》 论文地址&#xff1a;[2206.02647] Scaling Vision Transformers to Gigapixel Images via Hierarchical Self-Supervised Learning 项目地址&#xff1a;mahmoodlab/HI…

[ESP]从零开始的Arduino IDE安装与ESP环境配置教程

一、前言 最近也是在比赛方面比较忙&#xff0c;没有更多的时间和精力去更新长文章了。这几周都更倾向于环境搭建的教程&#xff0c;这类教程写起来确实方便&#xff0c;也不怎么费时间&#xff0c;一个下午基本可以搞定&#xff0c;哈哈&#xff0c;我保证不是在为自己想摆烂找…

投标心态:如何在“标海战术”中保持清醒的头脑?

在竞争激烈的市场环境下&#xff0c;“标海战术”——即大规模参与投标——已经成为许多企业争取市场份额的重要策略。然而&#xff0c;盲目追求投标数量可能导致资源浪费、团队疲劳以及战略目标的模糊化。在这种高强度的竞争模式中&#xff0c;如何保持清醒的头脑&#xff0c;…

wxWidgets使用wxStyledTextCtrl(Scintilla编辑器)的正确姿势

开发CuteMySQL/CuteSqlite开源客户端的时候&#xff0c;需要使用Scintilla编辑器&#xff0c;来高亮显示SQL语句&#xff0c;作为C/C领域最成熟稳定又小巧的开源编辑器&#xff0c;Scintilla提供了强大的功能&#xff0c;wxWidgets对Scintilla进行包装后的是控件类&#xff1a;…

【原生js案例】让你的移动页面实现自定义的上拉加载和下拉刷新

目前很多前端UI都是自带有上拉加载和下拉刷新功能,按照官网配置去实现即可,比如原生小程序,vantUI等UI框架,都替我们实现了内部功能。 那如何自己来实现一个上拉加载和下拉刷新的功能? 实现效果 不用浏览器的css滚动条,自定义实现滚动效果 自定义实现滚动,添加上拉加载…

批处理理解

初识批处理 如何批处理&#xff1a; 命名&#xff1a;.bat 方法&#xff1a;创建一个记事本文件&#xff0c;然后将其扩展改为.bat 批处理作用&#xff1a;自上而下成批处理每一条DOS命令&#xff0c;直到执行到最后一条。运行环境&#xff1a;当然是我们cmd了 回归我学过的…

APM32F411使用IIS外设驱动es8388实现自录自播

前言&#xff1a; 从零开始学习I2s外设&#xff0c;配置Es8288寄存器实现录音播放。本文章使用主控芯片是APM32F411系类。音频相关的概念比较多&#xff0c;就不再次做过多的介绍&#xff0c;本文章只是简单实现边录边播功能。APM系类兼容st的芯片&#xff0c;所以用st的hal库来…

OB删除1.5亿数据耗费2小时

目录 回顾&#xff1a;mysql是怎么删除数据的&#xff1f; 删除方案 代码实现 执行结果 结论 本篇是实际操作 批量处理数据以及线程池线程数设置 记录学习 背景&#xff1a;有一张用户标签表&#xff0c;存储数据量达4个亿&#xff0c;使用OceanBase存储&#xff0c;由于…

20241217使用M6000显卡在WIN10下跑whisper来识别中英文字幕

20241217使用M6000显卡在WIN10下跑whisper来识别中英文字幕 2024/12/17 17:21 缘起&#xff0c;最近需要识别法国电影《地下铁》的法语字幕&#xff0c;使用 字幕小工具V1.2【whisper套壳/GUI封装了】 无效。 那就是直接使用最原始的whisper来干了。 当你重装WIN10的时候&#…

linux普通用户使用sudo不需要输密码

1.root用户如果没有密码&#xff0c;先给root用户设置密码 sudo passwd root #设置密码 2.修改visudo配置 su #切换到root用户下 sudo visudo #修改visudo配置文件 用户名 ALL(ALL) NOPASSWD: ALL #下图所示处新增一行配置 用户名需要输入自己当前主机的用户名