首页 > 编程语言 >Java实现基于GDAL将单波段影像转为三波段影像-唯一值渲染

Java实现基于GDAL将单波段影像转为三波段影像-唯一值渲染

时间:2024-01-19 14:03:14浏览次数:32  
标签:styles short Java 影像 buffer 波段 Color import gdal


在处理遥感影像的渲染时,经常需要处理单波段影像。单波段影像没有任何颜色,只有一个波段的值。渲染时只能采用色带拉伸、离散颜色、唯一值渲染这几种方式。直接将单波段影像转成三波段的影像,并将三个波段转为颜色对应的rgb值,这样可以加速渲染、切片的过程。这里我有一张单波段影像,需要按照唯一值的方式,进行渲染,这里记录一下实现过程。

Java依赖

<dependency>
            <groupId>org.gdal</groupId>
            <artifactId>gdal</artifactId>
            <version>3.5.0</version>
        </dependency>

注意我本地部署的是gdal3以上的版本,不同版本的api会有不同

实现代码

package map.tile.server.tool;

import org.gdal.gdal.Band;
import org.gdal.gdal.Dataset;
import org.gdal.gdal.Driver;
import org.gdal.gdal.gdal;
import org.gdal.gdalconst.gdalconstConstants;

import java.awt.*;

import java.util.HashMap;
import java.util.Map;

import static org.gdal.gdalconst.gdalconstConstants.GDT_Byte;

public class RasterTool {

    public static void main(String[] args) throws Exception {
        // 注册所有支持的格式
        gdal.AllRegister();

        String inputFile = "E:\\栅格\\2023_20230430.tif";
        Dataset dataset = gdal.Open(inputFile, gdalconstConstants.GA_ReadOnly);

        if (dataset == null) {
            System.out.println("无法打开输入图像");
            return;
        }

        int width = dataset.GetRasterXSize();
        int height = dataset.GetRasterYSize();
        Band band = dataset.GetRasterBand(1);
        System.out.println(band.GetRasterDataType());


        //设立每类值对应样式,样色
        Color colorLevel1 = new Color(0, 92, 230);
        Color colorLevel2 = new Color(56, 168, 0);
        Color colorLevel3 = new Color(85, 255, 0);
        Color colorLevel4 = new Color(255, 170, 0);
        Map<Short, Color> styles = new HashMap<>(4);
        styles.put((short) 1, colorLevel1);
        styles.put((short) 2, colorLevel2);
        styles.put((short) 3, colorLevel3);
        styles.put((short) 4, colorLevel4);
        // 创建新的RGB图像对象
        Double[] noDataValue = new Double[1];
        band.GetNoDataValue(noDataValue);


        Driver driver = gdal.GetDriverByName("GTiff");
        Dataset rgbDataset = driver.Create("E:\\栅格\\output_rgb_image.tif", width, height, 3, GDT_Byte);
        rgbDataset.SetProjection(dataset.GetProjection());

        rgbDataset.SetGeoTransform(dataset.GetGeoTransform());
        for (int i = 0; i < 3; ++i) {
            Band outputBand = rgbDataset.GetRasterBand(i + 1);
            outputBand.SetNoDataValue(noDataValue[0]);

            short[] buffer = new short[width];
             //            一次读取一行,防止数据溢出
            for (int j = 0; j < height; j++) {
                band.ReadRaster(0, j, width, 1, buffer);
                // 转换颜色
                processData(buffer, i + 1, styles);
                outputBand.WriteRaster(0, j, width, 1, buffer);
            }
            outputBand.FlushCache();
            outputBand.delete();
        }
        rgbDataset.FlushCache();
        rgbDataset.delete();
        dataset.delete();
    }

    private static void processData(short[] buffer, int bandIndex, Map<Short, Color> styles) {
        if (bandIndex == 1) {
            for (int i = 0; i < buffer.length; i++) {
                Color color = styles.get(buffer[i]);
                if (color != null) {
                    buffer[i] = (short) color.getRed();
                }
            }

        } else if (bandIndex == 2) {
            for (int i = 0; i < buffer.length; i++) {
                Color color = styles.get(buffer[i]);
                if (color != null) {
                    buffer[i] = (short) color.getGreen();
                }
            }
        } else if (bandIndex == 3) {
            for (int i = 0; i < buffer.length; i++) {
                Color color = styles.get(buffer[i]);
                if (color != null) {
                    buffer[i] = (short) color.getBlue();
                }
            }
        }


    }
}

效果对比

将转换后的文件,直接拖入拖入QGIS展示效果如下:

  • 转换前

Java实现基于GDAL将单波段影像转为三波段影像-唯一值渲染_gdal

  • 转换后

注意,如果使用ArcGIS查看效果的话,需要将拉伸类型选择“无”,将应用Gamma拉伸取消勾选。

Java实现基于GDAL将单波段影像转为三波段影像-唯一值渲染_java_02

感想

  1. GDAL的Java交互真的不太友好
  2. 太大的影像居然没有办法直接读取,整张影像读取,因为可能或超过数组的长度限制。


标签:styles,short,Java,影像,buffer,波段,Color,import,gdal
From: https://blog.51cto.com/hanbogis/9329348

相关文章

  • qt和java的socket连接
    事先说明qt为客户端(发出请求)java为服务端(处理请求)关于qt的客户端来说我们大体上要完成三个需求,即请求连接,发送,接收请求连接如果想使用qt写socket程序,首先需要在.pro文件中添加QT+=network;(非常非常重要)接收然后我们就可以在代码中使用QT的网络库了,socket涉及到的函数库......
  • java线程核心原理
    1.线程的调度与时间片1.1java线程与操作系统现代操作系统(如Windows、Linux、Solaris)提供了强大的线程管理能力,Java不需要再进行自己独立的线程管理和调度,而是将线程调度工作委托给操作系统的调度进程去完成。在某些系统(比如Solaris操作系统)上,JVM甚至将每个Java线程一对一......
  • 深入理解JavaScript堆栈、事件循环、执行上下文、作用域以及闭包
    合集-JavaScript进阶系列(5) 1.JavaScriptthis绑定详解01-092.JavaScriptapply、call、bind函数详解01-093.JavaScriptforEach方法跳出循环01-024.深入理解JavaScript堆栈、事件循环、执行上下文和作用域以及闭包01-105.JavaScript到底应不应该加分号?JavaScript自......
  • java多态
    有两个类,一个Animal类,一个Cat类,其中Cat是Animal的子类,此时我在主函数中这样声明一个对象"Animalanimal=newCat();",此时animal实际上是Cat类此时,Animal类中没有catMouse()这个方法,Cat类中有这个方法,我在主函数声明了"Animalanimal=newCat();"后,无法调用animal.catchMouse();......
  • java相似度算法计算
     publicclassCompareStrSimUtil{privatestaticintcompare(Stringstr,Stringtarget,booleanisIgnore){intd[][];//矩阵intn=str.length();intm=target.length();inti;//遍历str的intj;//遍历......
  • HanLP — 汉字转拼音 -- JAVA
    目录语料库训练加载语料库训练模型保存模型加载模型计算调用HanLP在汉字转拼音时,可以解决多音字问题,显示输出声调,声母、韵母,通过训练语料库,本文代码为《自然语言处理入门》配套版本HanLP-1.7.5对重载不是重任进行转拼音,效果如下:原文:重载不是重任拼音(数字音调):chong2,zai3,bu......
  • docker构建java镜像,运行镜像出现 no main manifest attribute, in /xxx.jar
    背景本文主要是一个随笔,记录一下出现"nomainmanifestattribute"的解决办法问题原因主要是近期在构建一个镜像,在镜像构建成功后,运行一直提示"nomainmanifestattribute",但是还在想,是不是Dockerfile写错了,后来仔细检查了一下,发现是在pom文件下build节点下配置问题,修改配置......
  • java创建线程的4种方式
    1.Thread类一个线程在Java中使用一个Thread实例来描述。Thread类是Java语言一个重要的基础类,位于java.lang包中。Thread类有不少非常重要的属性和方法,用于存储和操作线程的描述信息。1.1线程ID属性:privatelongtid,此属性用于保存线程的ID。这是一个private类型属性,外......
  • Java里ArrayList中的toArray()用法
    深入理解List的toArray()方法和toArray(T[]a)方法这两个方法都是将列表List中的元素转导出为数组,不同的是,toArray()方法导出的是Object类型数组,而toArray[T[]a]方法导出的是指定类型的数组。下面是两个方法的申明及说明,摘自Java8的API文档。toArray()方法的分析Object[]toA......
  • 基于JAVA的新闻类网站
    21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到准确、快速、完善,并能提高工作管理效率,促进其发展。论文主要是对新闻类网站进行了介绍,包括研......