当前位置: 首页 > news >正文

使用Java绘制图片边框,解决微信小程序map组件中marker与label层级关系问题,label增加外边框后显示不能置与marker上面

今天上线的时候发现系统不同显示好像不一样,苹果手机打开的时候是正常的,但是一旦用安卓手机打开就会出现label不置顶的情况。尝试了很多种办法,也在官方查看了map相关的文档,发现并没有给label设置zIndex的属性,只看到了一个叫什么碰撞类型的属性,但是这个东西设置了如果两个目标有接触就会被隐藏掉,并不是我们想要的结果。

在这里插入图片描述
想了一下,如果我们不使用label生成边框呢,直接在服务器那边把图片绘制成有边框的不就好了,这样子只用marker就行了,就能得到iOS的效果了

问题截图

在这里插入图片描述

原本js代码

getBallCourtInfoByPoint(info).then((res) => {const len = res.length;for (let i = 0; i < len; i++) {const element = res[i];//获取质量最小的图片用于展示let newUrl = element.ballCourtImageList[0].ballCourtImage.replace(/(\.(jpg|jpeg|png|gif))$/, '-min100\$1');element['id'] = Number(element.id)element['markerId'] = Number(element.id)element['title'] = element.ballCourtNameelement['latitude'] = Number(element.lat)element['longitude'] = Number(element.lng)element['lat'] = Number(element.lat)element['lng'] = Number(element.lng)element['iconPath'] = newUrlelement['width'] = 38element['height'] = 38let label = {borderRadius: 8,borderWidth: 4,borderColor: '#fff',width: 38,height: 38,anchorX: -18,anchorY: -36,}element['label'] = label
});

在后端绘制好图片,编写ImageWithRoundedCorners类

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;public class ImageWithRoundedCorners {public static void main(String[] args) {try {// 加载原始图像BufferedImage originalImage = ImageIO.read(new File("C:\\Users\\Admin\\Desktop\\feitu\\img100\\tmp_8abe0efd9e58dfd1608a6f9affd987ef-e67efe7a-3fd8-482f-8f5d-30e686491a73.jpg"));// 设置padding和圆角半径int padding = 50; // 白色圆角区域的内边距(可以根据需求调整)int cornerRadius = 120; // 圆角的半径// 将图像裁剪成正方形,设置宽高400*400 (注意:一定要固定宽高)BufferedImage squareImage = cropToSquare(originalImage, 400, 400);// 创建带padding的圆角图像BufferedImage paddedRoundedImage = createPaddedRoundedImage(squareImage, cornerRadius, padding, Color.WHITE);// 保存结果图像ImageIO.write(paddedRoundedImage, "PNG", new File("C:\\Users\\Admin\\Desktop\\feitu\\img100\\1tmp_8abe0efd9e58dfd1608a6f9affd987ef-e67efe7a-3fd8-482f-8f5d-30e686491a73.jpg"));} catch (IOException e) {e.printStackTrace();}}//调用时候使用这个方法,把main注释掉
//    public static BufferedImage startImageWithRounded(BufferedImage originalImage) {
//
//        // 设置padding和圆角半径
//        int padding = 50; // 白色圆角区域的内边距(可以根据需求调整)
//        int cornerRadius = 120; // 圆角的半径
//
//        // 将图像裁剪成正方形,设置宽高400*400 (注意:一定要固定宽高)
//        BufferedImage squareImage = cropToSquare(originalImage, 400, 400);
//
//        // 创建带padding的圆角图像
//        BufferedImage paddedRoundedImage = createPaddedRoundedImage(squareImage, cornerRadius, padding, Color.WHITE);
//
//        return paddedRoundedImage;
//
//    }public static BufferedImage cropToSquare(BufferedImage originalImage, int targetWidth, int targetHeight) {int width = originalImage.getWidth();int height = originalImage.getHeight();// 计算目标区域与图像的宽高比double widthRatio = (double) targetWidth / width;double heightRatio = (double) targetHeight / height;// 选择较大的比例来保持图像的长宽比double scaleRatio = Math.max(widthRatio, heightRatio); // 使用较大的比例// 计算缩放后的图像尺寸int newWidth = (int) (width * scaleRatio);int newHeight = (int) (height * scaleRatio);// 创建一个新的图像用于缩放BufferedImage scaledImage = new BufferedImage(newWidth, newHeight, originalImage.getType());Graphics2D g2d = scaledImage.createGraphics();g2d.drawImage(originalImage, 0, 0, newWidth, newHeight, null);g2d.dispose();// 创建目标图像(固定宽高)BufferedImage finalImage = new BufferedImage(targetWidth, targetHeight, originalImage.getType());Graphics2D g2dFinal = finalImage.createGraphics();// 计算裁剪区域的位置,居中显示int xOffset = (newWidth - targetWidth) / 2;int yOffset = (newHeight - targetHeight) / 2;// 将缩放后的图像裁剪并绘制到目标图像上g2dFinal.drawImage(scaledImage, -xOffset, -yOffset, null);g2dFinal.dispose();return finalImage;}// 创建带padding和圆角的图像public static BufferedImage createPaddedRoundedImage(BufferedImage originalImage, int cornerRadius, int padding, Color backgroundColor) {int originalWidth = originalImage.getWidth();int originalHeight = originalImage.getHeight();// 计算新图像的宽度和高度,包含paddingint newWidth = Math.max(originalWidth, originalHeight) + 2 * padding; // 选择最大宽度或高度,确保裁剪时是正方形int newHeight = newWidth;  // 确保是正方形的裁剪区域// 动态调整cornerRadius,确保不会超过图像的宽度或高度的一半int maxCornerRadius = Math.min(originalWidth, originalHeight) / 2;cornerRadius = Math.min(cornerRadius, maxCornerRadius);  // 防止圆角半径太大// 创建一个新的BufferedImage来包含带有padding的图像BufferedImage paddedRoundedImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_ARGB);// 获取Graphics2D对象Graphics2D g2d = paddedRoundedImage.createGraphics();// 启用抗锯齿渲染提示g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 启用抗锯齿g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); // 设置高质量插值g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); // 优化质量// 填充背景颜色g2d.setColor(backgroundColor);g2d.fillRoundRect(0, 0, newWidth, newHeight, cornerRadius, cornerRadius); // 绘制带圆角的背景// 设置裁剪区域为圆角矩形,确保裁剪区域大小是填充后的正方形区域g2d.setClip(new RoundRectangle2D.Double(padding, padding, originalWidth, originalHeight, cornerRadius, cornerRadius));// 在新的图像上绘制原始图像(原图绘制到内边距后的区域)g2d.drawImage(originalImage, padding, padding, null);// 清理资源g2d.dispose();return paddedRoundedImage;}}

在这里插入图片描述

这个时候我们只需要读取生成好的图片即可,直接使用marker把label注释即可。

在这里插入图片描述

修改后的js代码

getBallCourtInfoByPoint(info).then((res) => {const len = res.length;for (let i = 0; i < len; i++) {const element = res[i];//获取质量最小的图片用于展示let newUrl = element.ballCourtImageList[0].ballCourtImage.replace(/(\.(jpg|jpeg|png|gif))$/, '-min100\$1');element['id'] = Number(element.id)element['markerId'] = Number(element.id)element['title'] = element.ballCourtNameelement['latitude'] = Number(element.lat)element['longitude'] = Number(element.lng)element['lat'] = Number(element.lat)element['lng'] = Number(element.lng)element['iconPath'] = newUrlelement['width'] = 38element['height'] = 38
//    let label = {
//      borderRadius: 8,
//      borderWidth: 4,
//      borderColor: '#fff',
//      width: 38,
//      height: 38,
//      anchorX: -18,
//      anchorY: -36,
//    }
//    element['label'] = label
});

还有一个问题,就是微信小程序读取较大的图片的时候会非常的慢,比如1M左右的图片就非常的慢了。我这里使用了MinIO文件系统存储图片,我会将用户上传的图片分割成两张图片,一张是原图,另一张是质量最小的图片,大概就是几十KB,读取的时候只需要读取几十KB的图片即可,等到用户查看详情再读取原图,所以为什么我这里读取了-min64结尾的图片。

//获取质量最小的图片用于展示
let newUrl = element.ballCourtImageList[0].ballCourtImage.replace(/(\.(jpg|jpeg|png|gif))$/, '-min100\$1');

详细请参考我的另一篇MinIO文章:https://blog.csdn.net/weixin_44912902/article/details/140353870

在这里插入图片描述

相关文章:

使用Java绘制图片边框,解决微信小程序map组件中marker与label层级关系问题,label增加外边框后显示不能置与marker上面

今天上线的时候发现系统不同显示好像不一样&#xff0c;苹果手机打开的时候是正常的&#xff0c;但是一旦用安卓手机打开就会出现label不置顶的情况。尝试了很多种办法&#xff0c;也在官方查看了map相关的文档&#xff0c;发现并没有给label设置zIndex的属性&#xff0c;只看到…...

力扣 LeetCode 142. 环形链表II(Day2:链表)

解题思路&#xff1a; 使用set判断是否重复添加&#xff0c;如果set加入不进去证明之前到达过该节点&#xff0c;有环 public class Solution {public ListNode detectCycle(ListNode head) {Set<ListNode> set new HashSet<>();ListNode cur head;while (cur …...

用MVVM设计模式提升WPF开发体验:分层架构与绑定实例解析

MVVM&#xff08;Model-View-ViewModel&#xff09;是一种架构模式&#xff0c;广泛应用于现代前端开发&#xff0c;尤其是在微软的WPF&#xff08;Windows Presentation Foundation&#xff09;应用程序中。它旨在通过将视图&#xff08;UI&#xff09;与业务逻辑&#xff08;…...

C++中的动态断言和静态断言

C中包含动态断言&#xff08;assert&#xff09;和静态断言&#xff08;static_assert&#xff09;&#xff0c;下面分别分析各自的用法。 1.动态断言&#xff08;assert&#xff09; assert 是一个宏&#xff0c;在预处理阶段不生效&#xff0c;在运行阶段才起作用&#xff0…...

运算放大器的学习(一)输入阻抗

输入阻抗 最近需要对运算放大器进行学习&#xff0c;我们后面逐一对其参数进行了解。 首先了解下输入阻抗。 放大电路技术指标测试示意图&#xff1a; 输入电阻&#xff1a; 从放大电路的输入端看进去的等效电阻称为放大电路的输入电阻&#xff0c;如上图&#xff0c;此处考虑…...

Rust枚举之卧龙凤雏(Rust Option枚举、Rust Result枚举)(Rust Enum、Some(T)、Ok(T)、Err(E))链式操作

文章目录 Rust 枚举之卧龙凤雏枚举的基本概念枚举定义示例 Result 枚举&#xff1a;凤雏Result 枚举的定义Result 的使用场景示例 1&#xff1a;文件读取示例 2&#xff1a;链式操作与错误处理 Option 枚举&#xff1a;卧龙Option 枚举的定义Option 的使用场景示例 1&#xff1…...

TCP/IP协议,TCP和UDP区别

TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff0c;传输控制协议/互联网协议&#xff09;是一组用于计算机网络中的通信协议&#xff0c;它为数据传输提供了标准框架&#xff0c;广泛用于互联网和局域网中。TCP/IP协议包括多个层次&#xff0c;每…...

【go从零单排】Timer、Epoch 时间函数

&#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 &#x1f4d7;概念 在 Go 语言中&#xff0c;time.Timer 是一个用于在指定时间后执行操作的计时器。…...

壁仞科技上市前最后一波 校招 社招 内推

随着美国大选结束&#xff0c;国内GPU 产业得到空前的的发展空间&#xff0c;国内芯片相关股票一片飘红。 国内大型 GPU厂商壁仞科技&#xff0c;摩尔线程等正紧锣密鼓地加紧上市。 GPGPU 芯片赛道来到了史无前例的红利点&#xff0c;抓住机会&#x1f4aa; 壁仞科技正在火热…...

【微软报告:多模态基础模型】(2)视觉理解

欢迎关注【youcans的AGI学习笔记】原创作品 【微软报告&#xff1a;多模态基础模型】&#xff08;1&#xff09;从专家到通用助手 【微软报告&#xff1a;多模态基础模型】&#xff08;2&#xff09;视觉理解 【微软报告&#xff1a;多模态基础模型】&#xff08;3&#xff09;…...

Linux 驱动

四十三、Linux设备树 43.1 DTS、DTB 和 DTC DTS 是设备树源码文件 DTB 是将DTS 编译以后得到的二进制文件。 DTC 工具将.dts 编译为.dtb 43.2 DTS语法 43.2.1 .dtsi 头文件 在.dts 设备树文件中&#xff0c;可以通过“#include”来引用.h、.dtsi 和.dts 文件。 …...

【数学二】线性代数-线性方程组-齐次线性方程组、非齐次线性方程组

考试要求 1、会用克拉默法则. 2、理解齐次线性方程组有非零解的充分必要条件及非齐次线性方程组有解的充分必要条件. 3、理解齐次线性方程组的基础解系及通解的概念,掌握齐次线性方程组基础解系和通解的求法. 4、理解非齐次线性方程组的解的结构及通解的概念. 5、会用初等行变…...

Git别名设置

在 Git 中设置命令别名可以让你更高效地使用常见的 Git 命令。通过为常用命令创建简短的别名&#xff0c;可以减少输入的字符数并加速工作流程。 参考链接 设置 Git 命令别名的方法&#xff1a; 使用 Git 配置命令&#xff1a; Git 允许通过 git config 命令来设置命令别名。这…...

算法基础 -- 红黑树原理与插入伪代码

红黑树原理与插入伪代码 红黑树的原理 红黑树是一种自平衡的二叉搜索树&#xff0c;通过对节点的颜色&#xff08;红色或黑色&#xff09;以及结构的约束条件来保持树的平衡。红黑树的原理可以通过以下五个特性描述&#xff1a; 节点是红色或黑色。根节点必须是黑色。所有叶…...

力扣 LeetCode 27. 移除元素(Day1:数组)

解题思路&#xff1a; 注意&#xff1a;数组只能覆盖&#xff0c;不能删除 erase方法的复杂度为O( n )而不是O( 1 )&#xff0c;因为需要把删除后后面的数组向前移动 方法一&#xff1a;双层for循环暴力 方法二&#xff1a;快慢指针 fast表示新数组的元素 slow表示新数组元…...

微服务链路追踪skywalking安装

‌SkyWalking是一个开源的分布式追踪系统&#xff0c;主要用于监控和分析微服务架构下的应用性能。‌ 它提供了分布式追踪、服务网格遥测分析、度量聚合和可视化一体化解决方案&#xff0c;特别适用于微服务、云原生架构和基于容器的环境&#xff08;如Docker、K8s、Mesos&…...

mqtt学习笔记(一)

以解决问题方式逐步学习探索 mqtt使用场景mqtt可能缺点mqtt学习疑问探索1、mqtt主题发布过的历史消息&#xff0c;全新连接的client能消费到吗&#xff1f;2、mqtt的client掉线如何重连&#xff0c;重连后订阅的topic配置还在不&#xff1f;3、mqtt的client掉线重连后&#xff…...

Kafka Eagle 安装教程

目录 前言 一、安装前的准备 1. 系统要求 2. 安装 JDK 3. 安装 Kafka 和 Zookeeper 4. MySQL 环境准备 二、下载并安装 Kafka Eagle 三、配置 Kafka Eagle 1. 编辑配置文件 2. 配置 Kafka 和 Zookeeper 信息 四、启动 Kafka Eagle 五、访问 Kafka Eagle 六、测试功…...

Ajax 获取进度和中断请求

HTML加入一些内容方便看效果和做交互&#xff1a; <div><p>当前传输进度&#xff1a;<span id"progress">0%</span></p><button id"send">发送</button><button id"btn">中断</button> …...

实验5:网络设备发现、管理和维护

实验5&#xff1a;网络设备发现、管理和维护 实验目的及要求&#xff1a; 通过实验&#xff0c;掌握Cisco 路由器和交换机的IOS配置管理。自动从NTP服务器获取时间信息。能够利用TFTP服务器实现路由器和交换机配置文件的备份和恢复。同时验证CDP协议和LLDP协议的网络参数。完…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...