基于定位的热力图展示,后端实现

首先将实际坐标转换成像素坐标

操作图片像素 不断的增加像素RGB值

扩大像素点范围,根据聚集程度设置色阶,最后高斯模糊形成热力图

这里是根据实际场景自动生成对应等比例大小的透明贴图,当然也可以直接在指定的图片上画热力图

1.坐标转换以前有发过一个工具类任意坐标系转换可以去看看

这里取的4个点分别为图片左下角,图片右上角 对应的实际位置坐标左下角和右上角

使用工具类获取到偏移量,旋转值等基本参数

double rotation = Math.toRadians(Math.abs(coordinateUtil.getAngle(imgPoint1, imgPoint2) - coordinateUtil.getAngle(mapPoint1, mapPoint2)));

double scale = coordinateUtil.getScale(mapPoint1, imgPoint1, mapPoint2, imgPoint2);

double tx = coordinateUtil.getXTranslation(mapPoint1, imgPoint1, rotation, scale);

double ty = coordinateUtil.getYTranslation(mapPoint1, imgPoint1, rotation, scale);

将实际点转换成像素点

Point boePoint = coordinateUtil.transformBoePoint(new Point(o.getX(), o.getZ(), 0.0), rotation, scale, tx, ty);

//去吹掉超出图片范围的点

//若转换的坐标超出了图片范围舍弃

Double x = boePoint.getX();

Double y = boePoint.getY();

if (!(x < 0 || y < 0 || x > imageWidth || y > imageHeight)){

heatMapData.setX(x)

.setY(y);

heatMapDataList.add(heatMapData);

}

渲染图片 这里说明下,因为像素点的坐标系原点是左上角的点,与我们最开始设置的对应坐标系不同,所有转换出来的像素点的y值需要用图片高度减去他剩下的就是实际的像素点,因为像素点很小,在设置时count我是默认将该点周围8个点作为一个大的像素点,这样在设置颜色时就会很明显,这个参数根据需求设置

/**

* 渲染图片

* @param image 图片流

* @param x 操作的像素点x

* @param y 操作的像素点y

* @param count 渲染的像素点

*/

public static void renderPictures(BufferedImage image, Double x, Double y, int count){

//获取画笔对象

int xValue = x.intValue();

int yValue = y.intValue();

int pixel = image.getRGB(xValue, yValue);

//从pixel中获取rgba的值

int b = (0xff & pixel);

int g = (0xff & (pixel >> 8));

int r = (0xff & (pixel >> 16));

//α通道值

int alpha = (0xff & (pixel >> 24));

//颜色解析

if (r == 0){

if (g < 255){

g = 255;

}

}

int rgb = b + (g << 8) + (r << 16) + (255 << 24);

int vy = image.getHeight() - yValue;

// image.setRGB(xValue, vy, rgb);

// image.setRGB(xValue, vy, rgb);

// image.setRGB(xValue, vy, rgb);

// image.setRGB(xValue, vy, rgb);

for (int i = xValue - count; i< xValue + count; i++) {

for (int j = vy - count; j< vy + count; j++) {

if (i >= 0 && i < image.getWidth()) {

if (j >=0 && j < image.getHeight() ) {

image.setRGB(i, j, rgb);

}

}

}

}

}

最后高斯模糊刚才处理后的图片,根据α通道设置色阶,实现多个目标聚集时颜色加深(这里色阶可根据实际情况调整)

/**

* 高斯模糊 设置色阶

* @param blur

* @param outPat

*/

public static void gaussFuzzy(BufferedImage blur, String outPat) {

try {

blur = HeatMapUtil.blur(blur, 25);

int width = blur.getWidth();

int height = blur.getHeight();

//获取像素点

for (int i = 0; i< width; i++) {

for (int j = 0; j < height; j++) {

int pixel = blur.getRGB(i, j);

//从pixel中获取rgba的值

int a = (pixel >> 24) & 0xff;

int g = (pixel >> 8) & 0xff;

if (g == 255) {

//颜色分级

if (a > 0 && a <= 25){

blur.setRGB(i, j, new Color(0, 0, 255, 15).getRGB());

}

if (a > 25 && a <= 50){

blur.setRGB(i, j, new Color(0, 255, 0, 160).getRGB());

}

if (a > 50 && a <= 100){

blur.setRGB(i, j, new Color(255, 255, 0, 185).getRGB());

}

if (a > 100 && a <= 125){

blur.setRGB(i, j, new Color(255, 213, 0, 200).getRGB());

}

if (a > 125 && a <= 150){

blur.setRGB(i, j, new Color(255, 171, 0, 215).getRGB());

}

if (a > 125 && a <= 150){

blur.setRGB(i, j, new Color(255, 129, 0, 225).getRGB());

}

if (a > 150 && a <= 175){

blur.setRGB(i, j, new Color(255, 87, 0, 235).getRGB());

}

if (a > 175 && a <= 200){

blur.setRGB(i, j, new Color(255, 42, 0, 245).getRGB());

}

if (a > 200){

blur.setRGB(i, j, new Color(255, 0, 0, 255).getRGB());

}

}

}

}

blur = HeatMapUtil.blur(blur, 10);

//输出

ImageIO.write(blur,"png",new File(outPat));

} catch (IOException e) {

e.printStackTrace();

}

}

/**

* 高斯模糊

* @param source 数据源

* @param radius 模糊半径

* @return

*/

public static BufferedImage blur(BufferedImage source, int radius) {

BufferedImage img = new BufferedImage(source.getWidth() + radius

* 2, source.getHeight() + radius * 2,

BufferedImage.TRANSLUCENT);

Graphics2D g2 = (Graphics2D) img.getGraphics();

g2.setColor(new Color(0,0,0,0));

g2.fillRect(0, 0, source.getWidth() + radius * 2,

source.getHeight() + radius * 2);

g2.drawImage(source, radius, radius, null);

g2.dispose();

int square = radius * radius;

float sum = 0;

float[] matrix = new float[square];

for (int i = 0; i < square; i++) {

int dx = i % radius - radius / 2;

int dy = i / radius - radius / 2;

matrix[i] = (float) (radius - Math.sqrt(dx * dx + dy * dy));

sum += matrix[i];

}

for (int i = 0; i < square; i++) {

matrix[i] /= sum;

}

BufferedImageOp op = new ConvolveOp(new Kernel(radius, radius,

matrix), ConvolveOp.EDGE_ZERO_FILL, null);

BufferedImage res = op.filter(img, null);

BufferedImage out = new BufferedImage(source.getWidth(),

source.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);

Graphics2D g3 = (Graphics2D) out.getGraphics();

g3.drawImage(res, -radius, -radius, null);

g3.dispose();

return out;

}

JAVA生成热点图,JAVA 后端生成热力图图片返回相关推荐

  1. java echarts 生成图片_java后端生成echarts图片

    一.所需工具 1.phantomjs 2.EChartsConvert 二.Maven依赖 org.freemarker freemarker 2.3.28 org.apache.httpcompon ...

  2. java createjpeg4_在linux下用java的JPEGCodec.createJPEGEncoder(bos)生成jpg图片问题

    在rh8   linux   下用java的JPEGCodec.createJPEGEncoder(bos)生成jpg图片,XServer已启动.出现如下问题 错误提示如下 java.lang.Int ...

  3. java按像素压缩,生成压缩图片。

    package com.yj.until;import java.awt.geom.AffineTransform; import java.awt.image.AffineTransformOp; ...

  4. Java 算法合并 Geoserver 切片生成指北针图片:高效、优雅解决地图数据可视化问题

    实现逻辑: 安装 Java 开发环境和 GeoTools 库.GeoTools 是一个 Java 库,可以用于处理和操作地理空间数据.可以从 GeoTools 的官网上下载最新版本的库,然后将其添加到 ...

  5. Docker打包项目部署的时候后端生成的图片验证码不显示

    原因是因为大部分的docker打包教程给予的项目中的docker配置文件中的jdk依赖都不是完整版,导致会有一些包没有   所以会导致标题之类的问题 搭建教程:https://blog.csdn.ne ...

  6. Java后端生成Echarts并渲染Word转PDF

    生成pdf文件 文件要素 文件中包含图片 文件中包含列表 文件中包含表格 文件中包含循环嵌套写入的内容 文件需要后端生成echarts图表数据 基于以上几点考虑 技术选取 方式一 itext7是一款用 ...

  7. java后端生成微信分享图片:使用freemarker、cssbox

    使用freemarker.cssbox生成微信分享图片 1. 生成微信图片我所想的有两种方式 利用图片水印来制作,可以先制作好想要的模板在利用水印将相应的内容添加打相应的位置完成 利用freemark ...

  8. Java纯后端生成PDF格式报表的三种方案(包含echarts图表)

    最近做了一个奇葩的需求,研究了一下Java纯后端生成PDF报表的方案,顺便将研究的方案做个总结复盘,分享一下. 需求分析:Java后端定时任务统计汇总成报表数据,并生成PDF格式的报表文件,并通过邮件 ...

  9. Java后端生成二维码(QrCode)

    引入依赖 <!-- 生成二维码所需依赖 --><dependency><groupId>commons-lang</groupId><artifa ...

最新文章

  1. Linux上 Can‘t connect to X11 window server using XX as the value of the DISPLAY 错误解决方法
  2. 死锁的4个必要条件和处理策略
  3. python重复import_Python module重复载入的问题
  4. 爬虫必须得会的预备知识
  5. linux中fg jobs ctrl-z bg操作和kill-15、kill-9杀死进程
  6. java中的年轻态,14、Java垃圾回收机制(示例代码)
  7. Java概览(java语言编程艺术笔记)
  8. git只提交一张图片_即使只使用一张静止的图片,也能制作出带有动感天空的视频...
  9. 如何编写一个抢购bot_如何编写一个SkyWalking插件
  10. 美团HD(7)-添加取消搜索按钮
  11. Ubuntu下载Linux源码 编译Linux源码
  12. Luogu P3174 [HAOI2009]毛毛虫 (树形dp)
  13. Ran 0 tests in 0.000s
  14. 蓝凌oa任意文件读取,RCE
  15. 关于java中xml文档解析
  16. Flutter InkWell Ink组件
  17. HDU 6148 - Valley Numer(数位DP)
  18. 【计科快速入门】一、计算机早期历史
  19. 将12小时制改为24小时制
  20. android8 twrp 小米6,小米6 第三方twrp中文Recovery3.2.3-0刷入工具|支持ROOT|自动解密data分区...

热门文章

  1. java switch的意思_java switch
  2. 一例Vmware虚拟化Vcenter连接不上解决过程。
  3. 社群运营,做好社群长期活跃可以从哪些方面入手?
  4. 高压电控产品电气设计入门与进阶(下)
  5. 【校招笔试】网易校招网络笔试题,菜的抠脚,蠢的流泪
  6. Python版按键精灵基础代码
  7. c语言转义字符空格符号,C语言 转义符\t占用几个空格
  8. bw_mem 内存_TCP:内存不足—考虑调整tcp_mem
  9. 生产环境Centos LNMP编译安装nginx-1.6 MySQL-5.6 php-5.5
  10. 教师使用计算机备课,计算机教师备课的几点看法