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

news2024/11/14 19:54:33

今天上线的时候发现系统不同显示好像不一样,苹果手机打开的时候是正常的,但是一旦用安卓手机打开就会出现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.ballCourtName
    element['latitude'] = Number(element.lat)
    element['longitude'] = Number(element.lng)
    element['lat'] = Number(element.lat)
    element['lng'] = Number(element.lng)
    element['iconPath'] = newUrl
    element['width'] = 38
    element['height'] = 38
    let 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();

        // 计算新图像的宽度和高度,包含padding
        int 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.ballCourtName
    element['latitude'] = Number(element.lat)
    element['longitude'] = Number(element.lng)
    element['lat'] = Number(element.lat)
    element['lng'] = Number(element.lng)
    element['iconPath'] = newUrl
    element['width'] = 38
    element['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

在这里插入图片描述

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

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

相关文章

【专题】计算机网络之网络层

1. 网络层的几个重要概念 1.1 网络层提供的两种服务 (1) 让网络负责可靠交付 计算机网络模仿电信网络&#xff0c;使用面向连接的通信方式。 通信之前先建立虚电路 VC (Virtual Circuit) (即连接)&#xff0c;以保证双方通信所需的一切网络资源。 如果再使用可靠传输的网络…

vTESTstudio系列15--vTESTstudio-Doors的需求和测试用例的管理

最近有朋友在咨询vTESTstudio中怎么去跟Doors里面的需求去做好管理这方面的问题&#xff0c;临时加两篇文章介绍一下,Lets Go!!! 目录 1.Doors的配置&#xff1a; 1.1 安装Doors AddIn for vTESTstudio&#xff1a; 1.2 更新XML脚本&#xff1a; 1.3 导出需求的Trace Item…

波动中的金钥匙:趋势震荡指标——源码公布,仅供学习

趋势与震荡&#xff0c;两者在市场运行中紧密相连&#xff0c;相互影响。趋势往往是震荡累积后的自然延伸&#xff0c;而震荡则常常是趋势形成与调整的前奏。在各类行情与不同时间周期中&#xff0c;当前的震荡不过是更大周期趋势中的一个组成部分&#xff1b;相应的&#xff0…

面试_ABtest原理简介

01 什么是ABtest ABtest来源于假设检验&#xff0c;现有两个随机均匀的有样本组A、B&#xff0c;对其中一个组A做出某种改动&#xff0c;实验结束后分析两组用户行为数据&#xff0c;通过显著性检验&#xff0c;判断这个改动对于我们所关注的核心指标是否有显著的影响&#xf…

‘nodemon‘ 不是内部或外部命令,也不是可运行的程序

解决方法&#xff1a;使用 npx 临时运行 nodemon 如果你不想全局安装 nodemon&#xff0c;你可以使用 npx&#xff08;npm 5.2 及以上版本自带&#xff09;来临时运行 nodemon&#xff1a; npx nodemon server.jsnodemon正常配置 要在开发过程中实现每次修改 Node.js 代码后…

计算机网络基础(3)_应用层自定义协议与序列化

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络基础(3)_应用层自定义协议与序列化 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&a…

E2E、CRC、Checksum、Rollingcounter

文章目录 前言1、E2E2、CRC3、Checksum4、Rollingcounter总结 前言 在专栏文章仿真CAN报文发送的CRC校验算法&#xff08;附CAPL代码&#xff09;和同星TSMaster中如何自定义E2E校验算法中分别给出了CRC算法和E2E校验实现&#xff0c;从中也明白了为什么在测试中需要去做这些仿…

嵌入式硬件杂谈(一)-推挽 开漏 高阻态 上拉电阻

引言&#xff1a;对于嵌入式硬件这个庞大的知识体系而言&#xff0c;太多离散的知识点很容易疏漏&#xff0c;因此对于这些容易忘记甚至不明白的知识点做成一个梳理&#xff0c;供大家参考以及学习&#xff0c;本文主要针对推挽、开漏、高阻态、上拉电阻这些知识点的学习。 目…

二叉树面试题(C 语言)

目录 1. 单值二叉树2. 相同的树3. 对称二叉树4. 二叉树的前序遍历5. 二叉树的中序遍历6. 二叉树的后序遍历7. 另一颗树的子树8. 通过前序遍历返回中序遍历 1. 单值二叉树 题目描述&#xff1a; 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有…

MFC中Excel的导入以及使用步骤

参考地址 在需要对EXCEL表进行操作的类中添加以下头文件&#xff1a;若出现大量错误将其放入stdafx.h中 #include "resource.h" // 主符号 #include "CWorkbook.h" //单个工作簿 #include "CRange.h" //区域类&#xff0c;对Excel大…

【C++】类中的“默认成员函数“--构造函数、析构函数、拷贝构造、赋值运算符重载

目录 "默认"成员函数 概念引入&#xff1a; 一、构造函数 问题引入&#xff1a; 1&#xff09;构造函数的概念 2&#xff09;构造函数实例 3&#xff09;构造函数的特性 4)关于默认生成的构造函数 (默认构造函数) 默认构造函数未完成初始化工作实例: 二…

LeetCode【0052】N皇后II

本文目录 1 中文题目2 求解方法&#xff1a;位运算回溯法2.1 方法思路2.2 Python代码2.3 复杂度分析 3 题目总结 1 中文题目 n 皇后问题 研究的是如何将 n 个皇后放置在 n n 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回 n 皇后问…

C语言-详细讲解-P1009 [NOIP1998 普及组] 高精度阶乘之和

目录 1.题目要求 2.题目解读 3.代码实现 4.一些小细节 1.数组储存大整数方式 2.memset函数介绍 3.digit与sum的关系 1.题目要求 2.题目解读 这道题本质就是高精度乘法高精度加法的结合&#xff0c;我之前有出过 高精度算法-保姆级讲解 希望详细了解的小伙伴可以去…

浅谈:基于三维场景的视频融合方法

视频融合技术的出现可以追溯到 1996 年 , Paul Debevec等 提出了与视点相关的纹理混合方法 。 也就是说 &#xff0c; 现实的漫游效果不是从摄像机的角度来看 &#xff0c; 但其仍然存在很多困难 。基于三维场景的视频融合 &#xff0c; 因其直观等特效在视频监控等相关领域有着…

Qt_day10_程序打包(完结)

目录 1. 设置图标 2. Debug和Release版本 3. 动态链接库 4. 打包 5. 联系项目要求 Qt开发的程序最终都是要给用户使用的&#xff0c;用户的电脑上不可能装一个Qt的开发环境导入项目使用。因此项目项目开发完成后需要打包——制作成安装包&#xff0c;用户直接下载并安装即可使用…

路径规划——RRT-Connect算法

路径规划——RRT-Connect算法 算法原理 RRT-Connect算法是在RRT算法的基础上进行的扩展&#xff0c;引入了双树生长&#xff0c;分别以起点和目标点为树的根节点同时扩展随机树从而实现对状态空间的快速搜索。在此算法中以两棵随机树建立连接为路径规划成功的条件。并且&…

【项目开发 | 跨域认证】JSON Web Token(JWT)

未经许可,不得转载。 文章目录 JWT设计背景:跨域认证JWT 原理JWT 结构JWT 使用方式注意JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案,本文介绍它的原理、结构及用法。 JWT设计背景:跨域认证 互联网服务的用户认证流程是现代应用中的核心组成部分,通常的流程…

学习笔记——PLCT:milk-v duo(持续更新)

买板子 官方标配有可能是单板&#xff08;如下图&#xff09;无工具包&#xff0c;记得买之前问一下客服。

Kubernetes-ArgoCD篇-01-简介

1、什么是Argo CD Argo CD 是针对 Kubernetes 的声明式 GitOps 持续交付工具。 Argo CD官方文档地址&#xff1a;https://argo-cd.readthedocs.io Argo CD源码地址&#xff1a;https://github.com/argoproj/argo-cd 1.1 关于Argo Argo是一个开源的项目&#xff0c;主要是扩…

【Python】轻松实现机器翻译:Transformers库使用教程

轻松实现机器翻译&#xff1a;Transformers库使用教程 近年来&#xff0c;机器翻译技术飞速发展&#xff0c;从传统的基于规则的翻译到统计机器翻译&#xff0c;再到如今流行的神经网络翻译模型&#xff0c;尤其是基于Transformer架构的模型&#xff0c;翻译效果已经有了质的飞…