Android 等高线绘图
来源:互联网 发布:java第一阶段测试题 编辑:程序博客网 时间:2024/04/28 18:34
Android 等高线绘图(又称热力图)
注:以下数据为一个一维的图片数组
注: 绘制方法来自https://github.com/ChristianFF/HeatMapForAndroid
https://github.com/HeartlandSoftware/AndroidHeatMap注:可使用两种方法绘制
使用高斯核密度估计方法绘制
使用绘制点阴影的方式绘制
使用高斯核密度估计方法绘制
- 主要流程:
- 处理数据
- 使用高斯核密度估计算计进行数组插值
- 根据所得数组绘制Bitmap
一、处理数据
根据一维的图片数组,转换成点坐标和值,封装到点对象里
//循环遍历数组 for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { n = i * HEIGHT + j; if (data[n] > startValue) { tmp_sum += data[n]; } tmp = (data[n] - startValue) / (endValue - 0); if (tmp > filter) { //根据数组值所在位置和值转换为点坐标和压力值 //clamp为一个工具方法,可根据(百分比,最小值,最大值),得出具体数值 addData(new DataPoint((int) (clamp((float) j / 60, 0.0f, mWidth)), (int) (clamp((float) i / 50, 0.0f, mHeight)), clamp(tmp, 0.0, 100.0))); } } }
二、使用高斯核密度估计算计进行数组插值
1.创建一个二维数组,大小依据要生成的bitmap大小相等,如
double[][] intensity = new double[mWidth + mRadius * 2][mHeight + mRadius * 2];
2.将上面处理好的点数据填充到该数组里面
for (DataPint w : mData) { int bucketX = w.x; int bucketY = w.y; if (bucketX < mWidth && bucketX >= 0 && bucketY < mHeight && bucketY >= 0) intensity[bucketX][bucketY] += w.intensity; }
3.使用高斯核密度估计算法处理该数组
double[][] convolved = convolve(intensity, mKernel); //高斯核密度估计算法 static double[][] convolve(double[][] grid, double[] kernel) { int radius = (int) Math.floor((double) kernel.length / 2.0); int dimOldW = grid.length; int dimOldH = grid[0].length; int dimW = dimOldW - 2 * radius; int dimH = dimOldH - 2 * radius; int lowerLimit = radius; int upperLimitW = radius + dimW - 1; int upperLimitH = radius + dimH - 1; double[][] intermediate = new double[dimOldW][dimOldH]; int x, y, x2, xUpperLimit, initial; double val; for (x = 0; x < dimOldW; x++) { for (y = 0; y < dimOldH; y++) { val = grid[x][y]; if (val != 0) { xUpperLimit = ((upperLimitW < x + radius) ? upperLimitW : x + radius) + 1; initial = (lowerLimit > x - radius) ? lowerLimit : x - radius; for (x2 = initial; x2 < xUpperLimit; x2++) { intermediate[x2][y] += val * kernel[x2 - (x - radius)]; } } } } double[][] outputGrid = new double[dimW][dimH]; int y2, yUpperLimit; for (x = lowerLimit; x < upperLimitW + 1; x++) { for (y = 0; y < dimOldH; y++) { val = intermediate[x][y]; if (val != 0) { yUpperLimit = ((upperLimitH < y + radius) ? upperLimitH : y + radius) + 1; initial = (lowerLimit > y - radius) ? lowerLimit : y - radius; for (y2 = initial; y2 < yUpperLimit; y2++) { outputGrid[x - radius][y2 - radius] += val * kernel[y2 - (y - radius)]; } } } } return outputGrid; }
其中mKernel为核数组,由以下方法所得
mKernel = generateKernel(mRadius, mRadius / 3.0); static double[] generateKernel(int radius, double sd) { double[] kernel = new double[radius * 2 + 1]; for (int i = -radius; i <= radius; i++) { kernel[i + radius] = (Math.exp(-i * i / (2 * sd * sd))); } return kernel; }
最终返回处理好的二维数组
三、根据所得数组绘制Bitmap
根据所得数组值计算图片每个像素的颜色并保存为数组
int i, j, index, col; double val; int colors[] = new int[dimW * dimH]; for (i = 0; i < dimH; i++) { for (j = 0; j < dimW; j++) { val = grid[j][i]; index = i * dimW + j; //根据值计算颜色,并插入对应的颜色数组中的位置 col = (int) (val * colorMapScaling); if (val != 0) { if (col < colorMap.length) colors[index] = colorMap[col]; else colors[index] = maxColor; } else { colors[index] = Color.TRANSPARENT; } } }
根据颜色数组,绘制Bitmap
Bitmap tile = Bitmap.createBitmap(dimW, dimH, Bitmap.Config.ARGB_8888); tile.setPixels(colors, 0, dimW, 0, 0, dimW, dimH);
使用绘制点阴影的方式绘制
- 主要流程
- 处理数据
- 绘制阴影
- 描绘颜色
- 生成Bitmap
一、处理数据处理数据
与上一种绘制方法相同
二、绘制阴影
创建一张bitmap,大小与最后所得bitmap相同
backBuffer = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);//使图片变透明backBuffer.eraseColor(Color.TRANSPARENT);
创建Canvas,并封装上得bitmap,并根据点数据进行画圆,并使之渐变透明,形成阴影
for (WeightedLatLng p : data) { drawAlphaCircle(p.x, p.y, p.intensity); }private void drawAlphaCircle(float x, float y, double intensity) { RadialGradient g = new RadialGradient(x, y, radius, Color.argb( (int) (intensity / maxIntensity * 255), 0, 0, 0), Color.TRANSPARENT, Shader.TileMode.CLAMP); Paint gp = new Paint(); gp.setShader(g); myCanvas.drawCircle(x, y, radius, gp); }
三、绘制颜色
创建渐变颜色条数组
private int colors[] = new int[]{0xffff0000, 0xff00ff00}; private float positions[] = new float[]{0.0f, 1.0f}; Bitmap bit = Bitmap.createBitmap(256, 1, Bitmap.Config.ARGB_4444); Canvas canvas = new Canvas(bit); LinearGradient grad; grad = new LinearGradient(0, 0, 256, 1, colors, positions, Shader.TileMode.CLAMP); Paint paint = new Paint(); paint.setStyle(Paint.Style.FILL); paint.setShader(grad); canvas.drawLine(0, 0, 256, 1, paint); palette = new int[256]; bit.getPixels(palette, 0, 256, 0, 0, 256, 1);
根据阴影透明度,绘制颜色
backBuffer.getPixels(pixels, 0, width, x, y, width, height); for (int j = 0; j < height; j++) { for (int i = 0; i < width; i++) { int pixel = pixels[i + (j * width)]; //the pixels alpha value (0-255) int alpha = 0xff & (pixel >> 24); //clamp the alpha value to user specified bounds int clampAlpha; if (alpha < maxOpacity) { if (alpha < minOpacity) { clampAlpha = minOpacity; } else { clampAlpha = alpha; } } else { clampAlpha = maxOpacity; } //set the pixels colour to its corresponding colour in the palette pixels[i + (j * width)] = ((0xff & clampAlpha) << 24) | (0xffffff & palette[alpha]); } }
四、生成Bitmap
backBuffer.setPixels(pixels, 0, width, x, y, width, height);
backBUffer为最终所得图片
* 源码可在上面GitHub上获取 , 或在 http://download.csdn.net/download/z896435317/9955057 下载
阅读全文
0 0
- Android 等高线绘图
- 等高线
- 等高线
- MATLAB绘制三维曲面图和等高线 绘图(2)
- android绘图
- android:绘图
- Android绘图
- android 绘图
- android:绘图
- Android 绘图
- Android绘图
- android 绘图
- Android绘图
- android绘图
- android绘图
- android绘图
- android 绘图
- Android---绘图
- 采样率150KSPS同步触发多板卡同步2路RS485D的3U PXIE采集卡
- IO中同步、异步与阻塞、非阻塞的区别
- 老翁关心母校南京大学的巡视整改进展
- ffmpeg 写的比较好的博客
- Spring Boot入门教程-集成Mybatis
- Android 等高线绘图
- 大数据之数据仓库
- webuploader上传按钮不能点击
- php导出excel表格
- linux发送文件到其他linux
- centos7安装
- 图片上传方法
- Android Fiddler抓包
- 1102:平方和与立方和