【JAVA】OPENGL+TIFF格式图片,不同阈值旋转效果

有些科学研究领域会用到一些TIFF格式图片,由于是多张图片相互渐变,看起来比较有意思:

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.*;/*** 可以自已定义日志打印格式,这样看起来比较方便些**/
class MyFormatter extends Formatter
{@Overridepublic String format(LogRecord arg0){//创建StringBuilder对象来存放后续需要打印的日志内容StringBuilder builder = new StringBuilder();//获取时间SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");Date now = new Date();String dateStr = simpleDateFormat.format(now);builder.append("[");builder.append(dateStr);builder.append(" ");//拼接日志级别builder.append(arg0.getLevel()).append(" ");builder.append(arg0.getSourceClassName()).append(" ");//拼接方法名builder.append(arg0.getSourceMethodName()).append(" ");StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();String line = stackTrace[8].toString();String lineNumber = line.substring(line.indexOf(":") + 1, line.length() - 1);//拼接方法名builder.append(lineNumber).append("] ");//拼接日志内容builder.append(arg0.getMessage());//日志换行builder.append("\r\n");return builder.toString();}
}public class MyLogger {static Logger logger;static  {logger = Logger.getLogger(MyLogger.class.getName());logger.setUseParentHandlers(false);//如果需要将日志文件写到文件系统中,需要创建一个FileHandler对象Handler consoleHandler = new ConsoleHandler();//创建日志格式文件:本次采用自定义的FormatterconsoleHandler.setFormatter(new MyFormatter());//将FileHandler对象添加到Logger对象中logger.addHandler(consoleHandler);}public static Logger getLogger() {return logger;}public static void main(String[] args) {MyLogger.logger.info("1");Logger logger = MyLogger.logger;logger.info("2");}
}

import com.sun.media.jai.codec.*;import com.sun.media.jai.codec.FileSeekableStream;
import com.sun.media.jai.codec.ImageDecoder;
import com.sun.media.jai.codec.ImageCodec;
import com.sun.media.jai.codec.TIFFEncodeParam;
import com.sun.media.jai.codec.TIFFDecodeParam;
import com.sun.media.jai.codec.JPEGEncodeParam;
import java.awt.image.RenderedImage;
import javax.media.jai.RenderedOp;
import javax.media.jai.JAI;import java.awt.*;
import java.awt.image.DataBuffer;
import java.awt.image.RenderedImage;
import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.*;//本类继承自画布类,用作绘图的面板,因为Java不允许多继承,所以要用此类
class TIFBase extends Canvas
{ImageDecoder dec;TIFBase() throws IOException {this.TifRead();}public void TifRead() throws IOException{String currentDir = System.getProperty("user.dir");System.out.println("当前目录:" + currentDir);//FileSeekableStream fileSeekableStream = new FileSeekableStream("human_brain_from_itk_example.tif");FileSeekableStream fileSeekableStream = new FileSeekableStream("ex_Repo_hb9_eve1.tif");TIFFDecodeParam param0 = null;TIFFEncodeParam param = new TIFFEncodeParam();JPEGEncodeParam param1 = new JPEGEncodeParam();dec = ImageCodec.createImageDecoder("tiff", fileSeekableStream, param0);param.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);param.setLittleEndian(false); // Intel}public ImageDecoder getDec() {return dec;}public void setDec(ImageDecoder dec) {this.dec = dec;}public void TifDisplay(Graphics g) throws IOException, InterruptedException{int pagesCount = dec.getNumPages();System.out.println("This TIF has " + pagesCount + " image(s)");System.out.println();for (int i = 0; i < pagesCount; i++){System.out.println("image: " + i);RenderedImage page = dec.decodeAsRenderedImage(i);DataBuffer dataBuffer = page.getData().getDataBuffer();//System.out.println("size: " + dataBuffer.getSize());int height = page.getHeight();int width = page.getWidth();//g.drawString(page.getData().toString(), 0, 0);for (int j = 0; j < height; j++){for (int k = 0; k < width; k++){int red = dataBuffer.getElem((j * width + k) * 3);int green = dataBuffer.getElem((j * width + k) * 3 + 1);int blue = dataBuffer.getElem((j * width + k) * 3 + 2);g.setColor(new Color(red, green, blue));g.drawOval(j, k, 1, 1);}}}//Thread.sleep(10);}public void TifDisplay2(Graphics g) throws IOException, InterruptedException {int pagesCount = dec.getNumPages();System.out.println("This TIF has " + pagesCount + " image(s)");System.out.println();DataBuffer[] dataBuffers = new DataBuffer[pagesCount];int height = 0;int width = 0;for (int i = 0; i < pagesCount; i++){//System.out.println("image: " + i);RenderedImage page = dec.decodeAsRenderedImage(i);//System.out.println("height: " + page.getHeight() + ", width: " + page.getWidth());height = page.getHeight();width = page.getWidth();dataBuffers[i] = page.getData().getDataBuffer();}int statPage = 0;int endPage = pagesCount;int gap = endPage - statPage;int miniColor = 3;for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){int redSumary = 0;int greenSumary = 0;int blueSumary = 0;int validRedColorFlag = 0;int validGreenColorFlag = 0;int validBlueColorFlag = 0;for (int k = statPage; k < endPage; k++){int red = dataBuffers[k].getElem((i * width + j) * 3);int green = dataBuffers[k].getElem((i * width + j) * 3 + 1);int blue = dataBuffers[k].getElem((i * width + j) * 3 + 2);if (red > miniColor){redSumary += red;validRedColorFlag++;}if (green > miniColor){greenSumary += green;validGreenColorFlag++;}if (blue > miniColor){blueSumary += blue;validBlueColorFlag++;}}redSumary = (validRedColorFlag == 0) ? 0 : (redSumary / validRedColorFlag);greenSumary = (validGreenColorFlag == 0) ? 0 : (greenSumary / validGreenColorFlag);blueSumary = (validBlueColorFlag == 0) ? 0 : (blueSumary / validBlueColorFlag);g.setColor(new Color(redSumary, greenSumary, blueSumary));g.drawOval(i, j, 1, 1);}}}// 把窗口拉宽些就可。public void paint(Graphics g){System.out.println("1");try {this.TifDisplay(g);//this.TifDisplay2(g);}catch (IOException | InterruptedException e){throw new RuntimeException(e);}}
}public class TIF extends JFrame
{public TIF(){super("画直线");this.setVisible(true);this.setBounds(200, 200, 600, 600);}public void Display() throws IOException{//创建对象TIFBase tifBase = new TIFBase();//创建实例this.getContentPane().add(tifBase);}public static void main(String[] args) throws IOException{TIF tif = new TIF();tif.Display();}
}
import com.sun.media.jai.codec.ImageDecoder;
import org.lwjgl.*;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;import java.awt.*;
import java.awt.image.DataBuffer;
import java.awt.image.RenderedImage;
import java.io.IOException;
import java.nio.*;
import java.util.Objects;
import java.util.logging.Logger;import static org.lwjgl.glfw.Callbacks.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL32.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;public class HelloWorld {// The window handleprivate long window;public static Logger logger = MyLogger.logger;private float angle;private ImageDecoder dec;private int threshold;HelloWorld()  {//创建对象try {TIFBase tifBase = new TIFBase();//创建实例dec = tifBase.getDec();} catch (IOException e) {throw new RuntimeException(e);}}public void run(){logger.info("Hello LWJGL " + Version.getVersion() + "!");init();loop();// Free the window callbacks and destroy the windowglfwFreeCallbacks(window);glfwDestroyWindow(window);// Terminate GLFW and free the error callbackglfwTerminate();Objects.requireNonNull(glfwSetErrorCallback(null)).free();}private void init() {logger.info("init");// Setup an error callback. The default implementation// will print the error message in System.err.GLFWErrorCallback.createPrint(System.err).set();angle = 5;threshold = 20;// Initialize GLFW. Most GLFW functions will not work before doing this.if ( !glfwInit() )throw new IllegalStateException("Unable to initialize GLFW");// Configure GLFWglfwDefaultWindowHints(); // optional, the current window hints are already the defaultglfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creationglfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable// Create the windowwindow = glfwCreateWindow(600, 600, "Hello World!", NULL, NULL);if ( window == NULL )throw new RuntimeException("Failed to create the GLFW window");// Setup a key callback. It will be called every time a key is pressed, repeated or released.glfwSetKeyCallback(window, (window, key, scancode, action, mods) -> {if ( key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE )glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop});// Get the thread stack and push a new frametry ( MemoryStack stack = stackPush() ) {IntBuffer pWidth = stack.mallocInt(1); // int*IntBuffer pHeight = stack.mallocInt(1); // int*// Get the window size passed to glfwCreateWindowglfwGetWindowSize(window, pWidth, pHeight);// Get the resolution of the primary monitorGLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());// Center the windowglfwSetWindowPos(window,(vidmode.width() - pWidth.get(0)) / 2,(vidmode.height() - pHeight.get(0)) / 2);} // the stack frame is popped automatically// Make the OpenGL context currentglfwMakeContextCurrent(window);// Enable v-syncglfwSwapInterval(1);// Make the window visibleglfwShowWindow(window);}/*** 绘制三角形*/public void DrawTriangles(){glTranslatef(-0.5f, -0.5f, -0.00f); //平移矩阵glRotatef(angle, 0.5f, 0.5f, 0.0f); //绕X,Y, Z轴直线旋转XX度glPointSize(1.0f);glBegin(GL_POINTS);try {int pagesCount = dec.getNumPages();//System.out.println("This TIF has " + pagesCount + " image(s)");//System.out.println();for (int i = 0; i < pagesCount; i++){//System.out.println("image: " + i);RenderedImage page = dec.decodeAsRenderedImage(i);DataBuffer dataBuffer = page.getData().getDataBuffer();//System.out.println("size: " + dataBuffer.getSize());int height = page.getHeight();int width = page.getWidth();//g.drawString(page.getData().toString(), 0, 0);for (int j = 0; j < height; j++){for (int k = 0; k < width; k++){int red = dataBuffer.getElem((j * width + k) * 3);int green = dataBuffer.getElem((j * width + k) * 3 + 1);int blue = dataBuffer.getElem((j * width + k) * 3 + 2);//g.setColor(new Color(red, green, blue));//System.out.println("red: " + red + ", green: " + green + ", blue: " + blue);if (red > threshold ){glColor3b((byte) red, (byte) 0, (byte) 0);glVertex3f(k / 200.0f,j / 200.0f,i / 200.0f);}if (green > threshold ){glColor3b((byte) 0, (byte) green, (byte) 0);glVertex3f(k / 200.0f,j / 200.0f,i / 200.0f);}if (blue > threshold ){glColor3b((byte) 0, (byte) 0, (byte) blue);glVertex3f(k / 200.0f,j / 200.0f,i / 200.0f);}//g.drawOval(j, k, 1, 1);}}}} catch (IOException e) {throw new RuntimeException(e);}System.out.println("threshold: " + threshold  + ", angle: " + angle);if (angle >= 350){angle = 0;threshold += 10;}angle+=10;glEnd();}public void DrawLines(){glBegin(GL_LINES);glVertex2i(0, 0);glVertex2i(0, 1);glEnd();}public void DrawQuads(){glBegin(GL_QUADS);//顶面glColor3f(0.0f, 1.0f, 0.0f);glVertex3f(1.0f, 1.0f, -1.0f);     //右上顶点glVertex3f(-1.0f, 1.0f, -1.0f);    //左上顶点glVertex3f(-1.0f, 1.0f, 1.0f);     //左下顶点glVertex3f(1.0f, 1.0f, 1.0f);      //右下顶点//底面glColor3f(1.0f, 0.5f, 0.0f);glVertex3f(1.0f, -1.0f, 1.0f);     //右上顶点glVertex3f(-1.0f, -1.0f, 1.0f);    //左上顶点glVertex3f(-1.0f, -1.0f, -1.0f);   //左下顶点glVertex3f(1.0f, -1.0f, -1.0f);    //右下顶点//前面glColor3f(1.0f, 0.0f, 0.0f);glVertex3f(1.0f, 1.0f, 1.0f);      //右上顶点glVertex3f(-1.0f, 1.0f, 1.0f);     //左上顶点glVertex3f(-1.0f, -1.0f, 1.0f);    //左下顶点glVertex3f(1.0f, -1.0f, 1.0f);     //右下顶点//后面glColor3f(1.0f, 1.0f, 0.0f);glVertex3f(1.0f, -1.0f, -1.0f);    //右上顶点glVertex3f(-1.0f, -1.0f, -1.0f);   //左上顶点glVertex3f(-1.0f, 1.0f, -1.0f);    //左下顶点glVertex3f(1.0f, 1.0f, -1.0f);     //右下顶点//左侧面glColor3f(0.0f, 0.0f, 1.0f);glVertex3f(-1.0f, 1.0f, 1.0f);     //右上顶点glVertex3f(-1.0f, 1.0f, -1.0f);    //左上顶点glVertex3f(-1.0f, -1.0f, -1.0f);   //左下顶点glVertex3f(-1.0f, -1.0f, 1.0f);     //右下顶点//右侧面glColor3f(1.0f, 0.0f, 1.0f);glVertex3f(1.0f, 1.0f, -1.0f);     //右上顶点glVertex3f(1.0f, 1.0f, 1.0f);      //左上顶点glVertex3f(1.0f, -1.0f, 1.0f);     //左下顶点glVertex3f(1.0f, -1.0f, -1.0f);    //右下顶点glEnd();}private void loop() {logger.info("loop");// This line is critical for LWJGL's interoperation with GLFW's// OpenGL context, or any context that is managed externally.// LWJGL detects the context that is current in the current thread,// creates the GLCapabilities instance and makes the OpenGLGL.createCapabilities();//DrawQuads();//-----------------------------------------//glLoadIdentity();   //重置当前的模型观察矩阵//————————————————//版权声明:本文为CSDN博主「贝勒里恩」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。//原文链接:https://blog.csdn.net/Mr_robot_strange/article/details/123682686while (true){//glClearColor(1.0f, 1.0f, 0.0f, 0.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除屏幕和深度缓存//-----------------------------------------glLoadIdentity();   //重置当前的模型观察矩阵//DrawLines();DrawTriangles();glfwSwapBuffers(window);glfwPollEvents();}}public static void main(String[] args) {logger.info("main");new HelloWorld().run();}}

这上边的代码如果需要运行,需要依赖这些JAR包: 

运行效果如下:

TIFF格式图片文件不同阈值旋转_哔哩哔哩_bilibili

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

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

相关文章

窗体控件(表格和控制器)

DataGridView 控件 DataGridView控件是C#中的一个Windows Forms控件&#xff0c;用于在应用程序中显示和编辑表格形式的数据。 先拖出四个label控件和四个TextBox控件和一个ComboBox和一个Button按钮&#xff0c;下面是一个DataGridView控件 准备一个Student类 namespace _窗…

八大算法排序@堆排序(C语言版本)

目录 堆排序大堆排序概念算法思想建堆建堆核心算法建堆的代码 排序代码实现 小堆排序代码实现时间复杂度空间复杂度 特性总结 堆排序 堆排序借用的是堆的特性来实现排序功能的。大堆需要满足父节点大于子节点&#xff0c;因此堆顶是整个数组中的最大元素。小堆则相反&#xff0…

码农的周末日常---2024/1/6

上周总结 按照规划进行开发&#xff0c;处事不惊&#xff0c;稳稳前行 2024.1.6 天气晴 温度适宜 AM 睡觉前不建议做决定是真的&#xff0c;昨天想着睡到中午&#xff0c;今天九点多醒了&#xff0c;得了&#xff0c;不想睡了 日常三连吧&#xff0c;…

【mars3d】new mars3d.layer.GeoJsonLayer({实现多孔面遮罩mask: true,

【mars3d】new mars3d.layer.GeoJsonLayer({实现多孔面遮罩 官网测试示例&#xff1a; 1.功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技 测试代码&#xff1a; export function showDraw(isFlyTo) { removeLayer() const geoJsonLayer new mars3d.layer.GeoJsonLaye…

神经网络-搭建小实战和Sequential的使用

CIFAR-10 model structure 通过已知参数&#xff08;高、宽、dilation1、kernel_size&#xff09;推断stride和padding的大小 网络 import torch from torch import nnclass Tudui(nn.Module):def __init__(self):super(Tudui, self).__init__()self.conv1 nn.Conv2d(in_chan…

TSConfig 配置(tsconfig.json)

详细总结一下TSConfig 的相关配置项。个人笔记&#xff0c;仅供参考&#xff0c;欢迎批评指正&#xff01; 另外&#xff0c;如果想了解更多ts相关知识&#xff0c;可以参考我的其他笔记&#xff1a; vue3ts开发干货笔记ts相关笔记&#xff08;基础必看&#xff09;ts相关笔记…

LeetCode-有效的字母异位词(242)

题目描述&#xff1a; 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断 t 是否是 s 的字母异位词。 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同&#xff0c;则称 s 和 t 互为字母异位词。 思路&#xff1a; 这题还是比较简单的&#xff0c;首先将两个字符…

盖子的c++小课堂——第二十三讲:背包问题

前言 又是一次漫长的更新&#xff08;我真不是故意的aaaaaaaaaaaaaaa&#xff09;&#xff0c;先不多说了&#xff0c;直接给我~坐下~说错了说错了&#xff0c;直接开始~ 背包问题----动态规划 背包问题&#xff08;knapsack problem&#xff09; 动态规划&#xff08;dyna…

基于python的leetcode算法介绍之动态规划

文章目录 零 算法介绍一 例题介绍 使用最小花费爬楼梯问题分析 Leetcode例题与思路[118. 杨辉三角](https://leetcode.cn/problems/pascals-triangle/)解题思路题解 [53. 最大子数组和](https://leetcode.cn/problems/maximum-subarray/)解题思路题解 [96. 不同的二叉搜索树](h…

企业出海数据合规:GDPR中的个人数据与非个人数据之区分

GDPR仅适用于个人数据&#xff0c;这意味着非个人数据不在其适用范围内。因此&#xff0c;个人数据的定义是一个至关重要的因素&#xff0c;因为它决定了处理数据的实体是否要遵守该法规对数据控制者规定的各种义务。尽管如此&#xff0c;什么是个人数据仍然是当前数据保护制度…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -小程序首页实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

Docker 镜像以及镜像分层

Docker 镜像以及镜像分层 1 什么是镜像2 Docker镜像加载原理2.1 UnionFs&#xff1a;联合文件系统2.2 Docker镜像加载原理2.3 Docker镜像的特点 3 镜像的分层结构4 可写的容器层 1 什么是镜像 镜像是一种轻量级、可执行的独立软件包&#xff0c;用来打包软件运行环境和基于运行…

数据处理四 基于图像hash进行数据整理(删除重复图片、基于模版查找图片)

一、背景知识 1.1 什么是hash Hash&#xff0c;一般翻译做“散列”&#xff0c;也有直接音译为“哈希”的&#xff0c;基本原理就是把任意长度的输入&#xff0c;通过Hash算法变成固定长度的输出。这个映射的规则就是对应的Hash算法&#xff0c;而原始数据映射后的二进制串就…

程序员必知!命令模式的实战应用与案例分析

命令模式是一种行为设计模式&#xff0c;它将请求封装为对象以实现客户端参数化、请求排队、日志记录及撤销操作&#xff0c;旨在解耦调用者与操作实现者&#xff0c;以智能家居为例&#xff0c;用户通过界面发送命令对象&#xff0c;设备作为接收者执行相应操作&#xff0c;无…

Ubuntu 安装Nginx服务

文章目录 前言一、Nginx安装1. Nginx默认安装2. Nginx指定版本安装3. Nginx验证4. Nginx服务控制4.1 查看服务状态4.2 停止服务4.3 启动服务4.4 重启服务 5. Nginx文件存放目录 二、自己编译Nginx1. 下载源码2. 依赖配置3. 编译 三、Nginx卸载总结 前言 Nginx&#xff08;发音为…

机器学习(四) -- 模型评估(3)

系列文章目录 机器学习&#xff08;一&#xff09; -- 概述 机器学习&#xff08;二&#xff09; -- 数据预处理&#xff08;1-3&#xff09; 机器学习&#xff08;三&#xff09; -- 特征工程&#xff08;1-2&#xff09; 机器学习&#xff08;四&#xff09; -- 模型评估…

探索 OceanBase 中图数据的实现

在数据管理和处理的现代环境中&#xff0c;对能够处理复杂数据结构的复杂数据模型和方法的需求从未如此迫切。图数据的出现以其自然直观地表示复杂关系的独特能力&#xff0c;开辟了数据分析的新领域。 虽然 Neo4j 等成熟的图形数据库为处理图形数据提供了强大的解决方案&…

如何理解Transformer论文中的positional encoding,和三角函数有什么关系?

大家好&#xff0c;我分享交流下这个问题。 Positional Encoding 掏出一张被无数人讲述的架构图。 Transformer 模型中的位置编码&#xff08;Positional Encoding&#xff09;是为了让模型能够考虑单词在句子中的位置。 由于 Transformer 的自注意力&#xff08;Self-Atte…

bat批处理文件_bat注释汇总

文章目录 1、示例&#xff08;直接结合脚本和结果进行理解&#xff09; 1、示例&#xff08;直接结合脚本和结果进行理解&#xff09; %这是一个注释% %这是另一个注释%rem 这是一个注释 rem 这是另一个注释:这是一个注释 ::这是一个注释 :?这是另一个注释if 1 1 ( %这里会执…

伐木工 - 华为OD统一考试

OD统一考试 题解&#xff1a; Java / Python / C 题目描述 一根X米长的树木&#xff0c;伐木工切割成不同长度的木材后进行交易&#xff0c;交易价格为每根木头长度的乘积。规定切割后的每根木头长度都为正整数,也可以不切割&#xff0c;直接拿整根树木进行交易。请问伐木工如…