- 浏览: 554796 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (162)
- 软件开发过程 (15)
- Java基础 (16)
- web开发 (20)
- Workflow应用 (0)
- 心情 (18)
- Oracle数据库 (26)
- MySQL数据库 (11)
- Struts应用 (9)
- Hibernate应用 (3)
- Spring应用 (1)
- C#开发 (0)
- iBatis应用 (0)
- Tomcat (10)
- PHP开发 (1)
- Linux (13)
- 设计原则总结 (1)
- 网站开发管理 (6)
- PowerDesigner (3)
- 系统架构 (3)
- 算法 (1)
- 国外接job (0)
- Lucene (1)
- Android (1)
- SEO技术 (1)
- Javascript (1)
最新评论
-
yu_meiguang:
真心感谢啊,找了半天才知道是这个以时间戳问题导致的问题
oracle分页查询数据重复问题 -
funnyone:
[u][b][i][flash=200,200][url][i ...
Oracle - Round函数 -
字母哥:
不错 今天用到了 时间戳排序的话有一样的就排序数据乱了
oracle分页查询数据重复问题 -
lelong:
xuhu_java 写道您好!我想问一下
select rou ...
Oracle - Round函数 -
xuhu_java:
您好!我想问一下select round(123456.788 ...
Oracle - Round函数
常有人说 Java 图形渲染很慢?嗯,相对 C/C++ 而言, Java2D 固有的图像处理能力确实有待提高。
但是,这也仅仅局限于对比 C/C++ 应用而言。
如果您是以其它什么东西与之比较,却得出 Java 渲染很慢的结论。那么,或者并不是出自 Java 本身的原因,而在于您并没能搞清楚该怎样正确的使用 Java 绘图。
况且,即便是相对于 C/C++ 而谈, Java 也并非相差到难以望其项背的地步。相对于某些行将就木的技术,至少我们除了异常积极的自行修改 JRE ,或者极端消极的等待 JRE 官方更新以外,还有使用 OpenGL 或者像素级优化这两条道路可走。
在本节当中,我们就先谈点基础的,来说说 Java 渲染的像素级优化吧。
像素与 RGB :
像素是什么?简单的讲,像素就是色彩,像素是系统能够在计算机屏幕上显示的最小染色点。越高位的像素,其拥有的色板也就越丰富,越能表达颜色的真实感。
众所周知,图像是像素的复合,看似绚丽的形象,也无外是一个个肉眼难以分辨的细微颗粒集合罢了。
比如,在一些常见的 Java 图像处理中,我们经常会用到所谓的 RGB24 模式( 24 位三原色模式,在 Java2D 中以 TYPE_INT_RGB 表示),将 Red , Green , Blue 三种色彩加以混合,创造出唯一的色彩点并绘制到计算机之上。而这个色彩点,也就是所谓的像素。因为在 RGB24 中 Red , Green , Blue 三者都被分配有一个 0~255 的强度值,所以该 RGB 模式的极限机能就是 256*256*256 ,即至多可以显示出 16777216 种颜色。
PS :关于 16 位的 RGB565 ( Java2D 中表示为 TYPE_USHORT_565_RGB )以及 RGB555 ( Java2D 中表示为 TYPE_USHORT_555_RGB )会在以后章节中涉及,大家此刻只要知道,使用 24 位以下的图形处理模式,在显示速度上虽然会有提高,视觉效果上却必然会有损失就可以了。
也许有网友会感叹。哇! 16777216 种颜色,这么多?难道都能用上吗?!
没错, 16777216 种颜色确实很多;事实上,这已非常接近于人类肉眼所能观察到的颜色数目极限 , 所以我们又将它称之为真彩色。然而,人类的欲求却是无止境的,即便能够展现出 16777216 种颜色的 RGB 真彩模式,依旧有人嫌弃它的效果太差。
否则,在您计算机“颜色质量”一栏中,或许就不会再有 32 位这种“多余”的选择了。
正是因为人类天性的贪婪,当今 2D 、 3D 图形渲染中最为常见的 ARGB 模式,也就是 32 位真彩模式才会应运而生。
ARGB 模式:
您问什么是 ARGB ?其实,它就是个穿了 Alpha 通道马甲的 RGB 。
例如,白色 ( 全强度 ) 用十六进制记数法表示为 : 0xFFFFFFFF 。而黑色正好相反;它在红色、绿色和蓝色中的任何一个通道中都无颜色,结果就成了 : 0xFF000000 。请注意 , Alpha 通道中的全强度意味着没有 Alpha (FF) ,也就是不透明 , 而无强度 (00) ,则意味着全透明。
public static int getARGB( int r, int g, int b, int alpha) {
return (alpha << 24) | (r << 16) | (g << 8) | b;
}
关于 BufferedImage :
当我们需要使用像素级操作,当我们需要设定针对不同图像的不同色彩模式时,最直接有效的方法,就是使用 BufferedImage 。
事实上,就像深入优化 Flash 渲染必须利用 BitmapData 一样,没有对 BufferedImage 的相关了解,提高 Java2D 性能根本无从谈起,甚至不能说你会用 Java2D 。
当您想要创建 BufferedImage ,并对其中像素进行直接操作时,大体上有三种方式可选:
1 、直接创建 BufferedImage ,导出 DataBufferInt 对象获取像素集合。
// 创建一个 640x480 的 BufferedImage ,设定渲染模式为 ARGB
BufferedImage image = new BufferedImage (640, 480,
BufferedImage . TYPE_INT_ARGB );
// 获得当前 BufferedImage 的图像数据存储器,并转为 DataBufferInt
DataBufferInt dataBuffer = ((DataBufferInt) image.getRaster()
.getDataBuffer());
// 获得对应 BufferedImage 的像素数组
int [] pixels = dataBuffer.getData();
2 、以 int[] 生成 WritableRaster ,以 WritableRaster 产生 BufferedImage 。
// 设定 BufferedImage 的宽与高
int width = 640, height = 480;
int size = width * height;
// 创建数组,用以保存对应 BufferedImage 的像素集合
int [] pixels = new int [size];
// 以指定数组创建出指定大小的 DataBuffer
DataBuffer dataBuffer = new DataBufferInt(pixels, size);
// 创建一个 WritableRaster 对象,用以管理光栅
WritableRaster raster = Raster.createPackedRaster (dataBuffer, width, height,width, new int [] { 0xFF0000, 0xFF00, 0xFF }, null );
// 创建一个 24 位的 RGB 色彩模型,并填充相应的 R 、 G 、 B 掩码
DirectColorModel directColorModel = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
// 以下为 32 位 RGB 色彩模型
// DirectColorModel directColorModel = new DirectColorModel(32, 0xFF000000, 0xFF0000, 0xFF00, 0xFF);
// 生成 BufferedImage, 预设 Alpha ,无配置
BufferedImage image = new BufferedImage(directColorModel, raster, true , null );
3 、与方法 2 基本相同,唯一差别在于使用了 SampleModel
int width = 640, height = 480;
int size = width * height;
int [] pixels = new int [size];
// 24 位色彩模型
DirectColorModel directColorModel = new DirectColorModel(24, 0xFF0000,
0xFF00, 0xFF);
// 以 SinglePixelPackedSampleModel 构建像素包
SampleModel sample = new SinglePixelPackedSampleModel(
DataBuffer . TYPE_INT , width, height, new int [] { 0xFF0000,
0xFF00, 0xFF });
// 生成 DataBuffer
DataBuffer dataBuffer = new DataBufferInt(pixels, size);
// 以 SampleModel 及 DataBuffer 生成 WritableRaster
WritableRaster raster = Raster.createWritableRaster (sample, dataBuffer,
new Point(0, 0));
// 生成 BufferedImage
BufferedImage image = new BufferedImage(directColorModel, raster, true , null );
实际上,虽然表面上有所不同,但无论您采用以上何种方式获得 BufferedImage 及其对应的像素集合( PS: 此处并非一定要获得像素的 int[] 形式,如 short[] 、 byte[] 等各式亦可,请根据实际需求决定), pixels 对您而言都将成为一块保存有图像数据的内存区域,针对此 pixels 进行的任何修改,都将被直接反馈于 BufferedImage 之上。
得到了像素集合,我们又该如何将其应用到 Java2D 中呢?下面,我将介绍两个像素级 Java 渲染组件给大家参考。下面我们所使用到的一切操作,也都将围绕 pixels 这个以 int[] 形式出现的数组展开。
一、 古董级的 Processing
项目地址: http://processing.org/
这是一套完整的,开源的,兼顾 2D 与 3D 方面的 Java 渲染组件。事实上, Processing 在针对 Java2D 性能优化上的意义并不太大,因为它本来就不是为了解决性能问题而出现的。
Processing 所做的,更多的是一种效果优化,一种对 Java 语言的延伸。它希望人们能利用它对 Java 的扩充,以简单高效的方式实现绚丽夺目的图形效果。应该说, Processing 将 Java 的语法简化并将其运算结果 “ 感官化 ” ,让使用者能很快享有声光兼备的交互式多媒体作品。
由于 Processing 运行于 PApplet 之上,而 PApplet 继承自 Applet 。也就是说原本的 Processing 也是一种小程序,如果我们要将它应用在网页环境之外,要们就将 PApplet 插入到 Frame/JFrame 当中,要么就将其改写。
为了未来的演示更加方便,笔者选择了改写的道路,将其 PGraphics 渲染层直接封装。以下,是一个已经替换为 Processing 渲染的 LGame 示例:
- public class ProcessingBall extends Screen {
- class Ball {
- float x;
- float y;
- float speed;
- float gravity;
- float w;
- float life = 255 ;
- Ball(float tempX, float tempY, float tempW) {
- x = tempX;
- y = tempY;
- w = tempW;
- speed = 0 ;
- gravity = 0 .1f;
- }
- void move() {
- speed = speed + gravity;
- y = y + speed;
- if (y > getHeight()) {
- speed = speed * -0 .8f;
- y = getHeight();
- }
- }
- boolean finished() {
- life--;
- if (life < 0 ) {
- return true ;
- } else {
- return false ;
- }
- }
- void display(LPGraphics g) {
- g.fill(0 , life);
- g.ellipse(x, y, w, w);
- }
- }
- private ArrayList balls;
- private int ballWidth = 48 ;
- PImage image=Utils.loadImage("system/image/logo.png" );
- public ProcessingBall() {
- balls = new ArrayList();
- balls.add(new Ball(getWidth() / 2 , 0 , ballWidth));
- }
- public void draw(LPGraphics g) {
- g.background(255 );
- for ( int i = balls.size() - 1 ; i >= 0 ; i--) {
- Ball ball = (Ball) balls.get(i);
- ball.move();
- ball.display(g);
- if (ball.finished()) {
- balls.remove(i);
- }
- }
- }
- public void leftClick(MouseEvent e) {
- balls.add(new Ball(getMouseX(), getMouseY(), ballWidth));
- }
- public void middleClick(MouseEvent e) {
- }
- public void rightClick(MouseEvent e) {
- }
- public void onKey(KeyEvent e) {
- }
- public void onKeyUp(KeyEvent e) {
- }
- public static void main(String[] args) {
- GameScene frame = new GameScene( "球体下落" , 480 , 360 );
- Deploy deploy = frame.getDeploy();
- deploy.setScreen(new ProcessingBall());
- deploy.setShowFPS(true );
- deploy.setFPS(100 );
- deploy.mainLoop();
- frame.showFrame();
- }
- }
- public class ProcessingBall extends Screen {
- class Ball {
- float x;
- float y;
- float speed;
- float gravity;
- float w;
- float life = 255;
- Ball(float tempX, float tempY, float tempW) {
- x = tempX;
- y = tempY;
- w = tempW;
- speed = 0;
- gravity = 0.1f;
- }
- void move() {
- speed = speed + gravity;
- y = y + speed;
- if (y > getHeight()) {
- speed = speed * -0.8f;
- y = getHeight();
- }
- }
- boolean finished() {
- life--;
- if (life < 0) {
- return true;
- } else {
- return false;
- }
- }
- void display(LPGraphics g) {
- g.fill(0, life);
- g.ellipse(x, y, w, w);
- }
- }
- private ArrayList balls;
- private int ballWidth = 48;
- PImage image=Utils.loadImage("system/image/logo.png");
- public ProcessingBall() {
- balls = new ArrayList();
- balls.add(new Ball(getWidth() / 2, 0, ballWidth));
- }
- public void draw(LPGraphics g) {
- g.background(255);
- for (int i = balls.size() - 1; i >= 0; i--) {
- Ball ball = (Ball) balls.get(i);
- ball.move();
- ball.display(g);
- if (ball.finished()) {
- balls.remove(i);
- }
- }
- }
- public void leftClick(MouseEvent e) {
- balls.add(new Ball(getMouseX(), getMouseY(), ballWidth));
- }
-
public void middleClick(MouseEven
发表评论
-
Integer大小比较的问题
2014-05-22 12:29 638public static void main(String ... -
JAXB安装与编译器使用(转)
2013-06-07 14:59 1613JAXB (Java Architecture for XM ... -
Java中关于OutOfMemoryError的场景及解决方法
2012-12-17 10:18 50431、OOM for Heap=>例如:java.lang ... -
压缩代码
2012-05-11 13:38 0import java.io.ByteArrayInputSt ... -
Java性能故障排除工具(转)
2011-11-03 14:04 7081.jconsole是随着JDK 1.5而 ... -
静态类 static class (转载)
2011-05-18 02:31 1163转自:http://klcwt.iteye.com ... -
XML与DTD总结
2010-11-22 03:57 0DTD文件的作用是什么? 对标记编制文档 加强 ... -
Log4j 笔记
2010-08-19 09:18 1000困惑了很久的日志使用。用于记录自己的使用过程。 ... -
java.util.UUID 使用
2010-04-12 13:57 7704近来要生成一唯一标识,想不到java基础类库里有这种工具,记录 ... -
外企面试中常用到的英语问答
2008-10-13 23:42 1013找一份满意的工作吗?外企面试中面对外国老板连珠炮似的提问,有没 ... -
JAVA日期加减运算
2008-07-05 13:54 13760public static Date getBeforeMo ... -
JAVA中转义字符
2008-07-01 15:55 41281.八进制转义序列:\ + 1到3位5数字;范围'\000' ... -
使用java.text包格式化数字和日期
2008-06-27 09:48 1294在C中可以使用类似printf(“%d %8.2f\n”, 1 ... -
java 二进制兼容性 (转载)
2008-05-28 21:01 1906现在做的一个项目需要维持两个版本,一个ASP(Applica ... -
[转帖]ant中文教程(二)
2007-07-25 16:50 31123 编写build.xml Ant的buildfile是用 ... -
[转帖]ant中文教程(一)
2007-07-25 16:26 18861 Ant是什么? Apache Ant 是一个基于 Jav ... -
Java转义字符
2007-06-04 17:10 14啊 -
Struts 动态单选按钮组
2007-05-29 16:50 60一般情况,使用嵌套 Struts 标签 < ... -
整合Spring与Struts
2007-06-05 17:33 40环境:Eclipse3.2+tomcat5.5+mysql5. ... -
Portlet 是什么 ?
2007-04-12 10:01 8581Portlets “Portlets是 ...
相关推荐
否则,创建一个新的`BufferedImage`实例,其宽度和高度与原始`Image`相同,并根据`Image`的色彩模型和透明度选择适当的`BufferedImage`类型。然后,使用`Graphics2D`将`Image`绘制到`BufferedImage`上,完成转换过程...
public static BufferedImage iplToBufImgData(IplImage ipl,BufferedImage image ) public static IplImage BufImgToIplData(IplImage ipl,BufferedImage bi)
Java中的像素级图像处理与识别涉及到了多个关键概念和技术,主要使用了`BufferedImage`和`ImageIO`这两个核心类。下面将详细解释这些概念及其使用方法。 1. **ImageIO类**: `ImageIO`是Java标准库中处理图像输入...
进行像素级图像处理时,主要会用到`BufferedImage`和`ImageIO`这两个类。 - **`ImageIO`**:提供了图像读写接口,可以方便地从URL、输入流等地方获取图像信息。例如: ```java BufferedImage img = ImageIO.read...
下面,我们将深入分析与BMP文件格式相关的知识点,以及如何在Java中实现`BufferedImage`到BMP文件的转换。 ### BMP文件结构 BMP文件由多个部分组成,主要包括文件头(File Header)和信息头(Info Header),以及...
总之,Java提供了强大的图像处理能力,结合`ImageIO`和`BufferedImage`,开发者可以实现从基本的像素级操作到复杂的图像识别算法。在实际项目中,可以根据需求选择合适的方法,实现图像的读取、编辑、保存以及各种...
在Java编程语言中,`BufferedImage`类是用于创建和操作图像的重要工具。这个类提供了丰富的功能,包括读取、写入、绘制和修改图像。在这个特定的场景中,我们利用`BufferedImage`来实现一个有趣的功能:将四张图片...
然而,获取单个像素的颜色值,我们可以使用`BufferedImage`的`getRGB(int x, int y)`方法,它会返回指定位置(x, y)像素的ARGB值。例如,要获取图像左上角第一个像素的颜色,我们可以这样做: ```java int pixel =...
总结来说,理解和掌握`Mat`与`BufferedImage`之间的转换对于在Java环境中有效地使用OpenCV至关重要。无论是进行图像显示、保存还是进一步的处理,这种转换都是不可或缺的步骤。熟练运用这些转换方法,可以极大地扩展...
完成这些步骤后,你就成功地从JPEG文件生成了BufferedImage,并提取了图像的像素数据。这样的处理可以用于各种图像操作,如缩放、旋转、颜色转换或滤波。然而,由于Android不直接支持Java AWT,你可能需要使用...
BufferedImage 是 Java 中用于表示图像的类,它可以存储图像的像素数据和其他相关信息。使用 BufferedImage 获取图片尺寸可以通过以下步骤实现: 1. 首先,创建一个 BufferedImage 对象,并将其设置为读取指定图片...
1. **BufferedImage类**: `BufferedImage`是`Image`类的子类,它提供了对图像像素的直接访问。你可以通过创建一个`BufferedImage`对象并指定其类型(如RGB、ARGB等)来加载或创建图像。例如: ```java ...
6. **图像处理API**:在Java中,可以使用Java AWT(Abstract Window Toolkit)和Swing中的BufferedImage类进行基本的图像处理,或者利用更高级的Java Advanced Imaging (JAI) 库进行复杂的操作。这个jar包可能封装了...
2. **创建 BufferedImage 对象**:然后,我们需要创建一个 BufferedImage 对象,指定其宽度(WIDTH)、高度(HEIGHT)以及类型(BufferedImage.TYPE_INT_RGB,即 RGB 像素格式)。这样我们就得到了一个可以在内存中...
另一个是渲染线程,负责将游戏状态更新到屏幕上,确保游戏画面的连续滚动。通过合理调度这两个线程,可以保证游戏的流畅运行,避免因为CPU资源的争夺导致画面卡顿。 其次,IO流是数据在内存与外部设备之间传输的...
Java中使用BufferedImage判断图像通道顺序并转RGB/BGR 在Java中,使用BufferedImage处理图像时,需要判断图像的通道顺序,判断图像是否为RGB或BGR格式,并对其进行相应的转换。本文将详细介绍如何使用BufferedImage...
瓷砖木工将谷歌地图、ArcGIS、OpenStreetMaps 中的底图图块渲染为 java 中的 ,然后再渲染为 PNG。 状态: pre-alpha 与 Jenkins 的持续集成: Maven 站点报告在包括 。特征计算最佳缩放级别处理 180/-180 经度边界...
- 使用`createCompatibleImage()`方法创建一个新的`BufferedImage`对象,确保颜色模型与原始图像兼容,这样在绘制时能提高效率。 - 考虑性能:对于大量或大尺寸的图片,直接操作原始图像可能会很慢。可以先缩小...
了解图片的像素信息对很多场合都很关键,比如网页设计时需要考虑加载速度与清晰度的平衡,摄影后期处理时调整尺寸,甚至在进行图像分析和处理的算法开发时,都需要明确图像的像素大小。在日常工作中,掌握这些方法...
2. **计算比例**:确定新尺寸与原尺寸的比例,以保持宽高比不变。如果新的宽度或高度小于原始尺寸,可以计算出缩放比例。 3. **创建新图像**:创建一个新的`BufferedImage`对象,尺寸为新宽度和高度。 4. **像素复制...