java画图
前段时间项目里用到了画图,发布到服务器之后,图片处理程序报错:java.lang.IncompatibleClassChangeError:Found class com.sun.image.codec.jpeg.JPEGImageEncoder, but interface was expected
查了下服务器的JRE是用的openjdk,将openjdk换成SUN的标准JDK就可以了。
下面是个画图的简单例子:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
@SuppressWarnings("restriction")
public class Example {
public static void draw(){
/**
* BufferedImage(int width, int height, int imageType)
* 构造一个类型为预定义图像类型之一的 BufferedImage。
*/
BufferedImage bufferedImage = new BufferedImage(500, 300, BufferedImage.TYPE_3BYTE_BGR);
/**
* createGraphics() 创建一个 Graphics2D,可以将它绘制到此 BufferedImage 中。
*/
Graphics2D graphics2d = bufferedImage.createGraphics();
/**
* setBackground(Color color) 设置 Graphics2D 上下文的背景色。
*/
graphics2d.setBackground(Color.WHITE);
/**
* public abstract void clearRect(int x,int y,int width,int height)
* 通过使用当前绘图表面的背景色进行填充来清除指定的矩形。此操作不使用当前绘图模式。
* 从 Java 1.1 开始,离屏图像的背景色可能与系统相关。
* 应用程序应该使用 setColor,然后使用 fillRect,以确保离屏图像被清除为指定颜色。
* 参数:
* x - 要清除矩形的 x 坐标。
* y - 要清除矩形的 y 坐标。
* width - 要清除矩形的宽度。
* height - 要清除矩形的高度。
* */
graphics2d.clearRect(0, 0, 500, 300);
/**
* public abstract void setColor(Color c)
* 将此图形上下文的当前颜色设置为指定颜色。
* 使用此图形上下文的所有后续图形操作均使用这个指定的颜色。
* 参数:
* c - 新的呈现颜色。
* */
graphics2d.setColor(Color.RED);
Font font = new Font("sansserif", Font.PLAIN, 18);
/**
* 将此图形上下文的字体设置为指定字体。
* 使用此图形上下文的所有后续文本操作均使用此字体。忽略 null 参数
*/
graphics2d.setFont(font);
/**
* public abstract void fillRect(int x,int y,int width,int height)
* 填充指定的矩形。该矩形左边缘和右边缘分别位于 x 和 x + width - 1。
* 上边缘和下边缘分别位于 y 和 y + height - 1。
* 得到的矩形覆盖 width 像素宽乘以 height 像素高的区域。
* 使用图形上下文的当前颜色填充该矩形。
* */
graphics2d.fillRect(0, 0, 500, 30);
graphics2d.setColor(Color.WHITE);
graphics2d.drawString("简单的例子", 200, 20);
font = new Font("sansserif", Font.PLAIN, 16);
graphics2d.setFont(font);
graphics2d.setColor(Color.RED);
/**
* public abstract void fillOval(int x,int y,int width,int height)
* 使用当前颜色填充外接指定矩形框的椭圆。
* 参数:
* x - 要填充椭圆的左上角的 x 坐标。
* y - 要填充椭圆的左上角的 y 坐标。
* width - 要填充椭圆的宽度。
* height - 要填充椭圆的高度。
* */
graphics2d.fillOval(20, 40, 20, 20);
graphics2d.setColor(Color.ORANGE);
graphics2d.fillOval(40, 60, 20, 20);
graphics2d.setColor(Color.YELLOW);
graphics2d.fillOval(60, 80, 20, 20);
graphics2d.setColor(Color.GREEN);
graphics2d.fillOval(80, 100, 20, 20);
graphics2d.setColor(Color.CYAN);
graphics2d.fillOval(100, 120, 20, 20);
graphics2d.setColor(Color.BLUE);
graphics2d.fillOval(120, 140, 20, 20);
graphics2d.setColor(Color.MAGENTA);
graphics2d.fillOval(140, 160, 20, 20);
graphics2d.setColor(Color.MAGENTA);
graphics2d.fillOval(340, 160, 20, 20);
graphics2d.setColor(Color.BLUE);
graphics2d.fillOval(360, 140, 20, 20);
graphics2d.setColor(Color.CYAN);
graphics2d.fillOval(380, 120, 20, 20);
graphics2d.setColor(Color.GREEN);
graphics2d.fillOval(400, 100, 20, 20);
graphics2d.setColor(Color.YELLOW);
graphics2d.fillOval(420, 80, 20, 20);
graphics2d.setColor(Color.ORANGE);
graphics2d.fillOval(440, 60, 20, 20);
graphics2d.setColor(Color.RED);
graphics2d.fillOval(460, 40, 20, 20);
/**
* public abstract void drawLine(int x1,int y1,int x2,int y2)
* 在此图形上下文的坐标系中,使用当前颜色在点 (x1, y1) 和 (x2, y2) 之间画一条线。
* 参数:
* x1 - 第一个点的 x 坐标。
* y1 - 第一个点的 y 坐标。
* x2 - 第二个点的 x 坐标。
* y2 - 第二个点的 y 坐标。
* */
graphics2d.setColor(Color.RED);
for(int m=0;m<5;m++){
graphics2d.drawLine(0, 190+m*20, 500, 190+m*20);
}
graphics2d.setColor(Color.RED);
for(int n=0;n<25;n++){
graphics2d.drawLine(0+n*20, 190, 0+n*20, 270);
}
/**
* public abstract void dispose()释放此图形的上下文以及它使用的所有系统资源。
* 调用 dispose 之后,就不能再使用 Graphics 对象。
* Java 程序运行时,可以在一个短时间帧内创建大量的 Graphics 对象。
* 尽管垃圾回收器的终止进程也能够进行相同的系统资源释放,
* 但是最好通过调用此方法来手工释放相关资源,而不是依靠终止进程,
* 因为终止进程需要很长时间才能结束运行。
* 作为组件 paint 和 update 方法的参数提供的 Graphics 对象,
* 在这些方法返回时将被系统自动释放。
* 为了提高效率,仅当所使用的 Graphics 对象
* 是由组件或另一个 Graphics 对象直接创建时,
* 程序员才应在使用完此 Graphics 后调用 dispose。
* */
graphics2d.dispose();
/**
* public void flush()
* 刷新此 Image 对象正在使用的所有可重构的资源。
* 这包括为呈现到屏幕而缓存的所有像素数据,
* 以及用来存储图像数据或像素的所有系统资源(如果可以重新创建它们)。
* 图像被重置为与初始创建时类似的状态,因此如果再次呈现图像,
* 则必须重新创建图像数据或再次从源中获取这些数据。
* 此方法如何影响特定类型的 Image 对象的示例如下:
* BufferedImage 对象不改动存储其像素的主要 Raster,但是刷新有关像素的缓存信息,
* 比如上传到用于加速位图的显示硬件的副本。
* Image 对象由带有 width 和 height 参数的 Component 方法创建,
* 该方法不改动像素的主要缓冲区,但是释放所有缓存的信息,
* 这与对 BufferedImage 对象的操作非常类似。
* VolatileImage 对象释放其所有像素资源,
* 这些资源包括通常存储在缺乏资源的显示硬件上的主要副本。
* 这些对象稍后可以使用其 validate 方法还原。
* 卸载从文件、URL 中加载或由 ImageProducer 生成的 Toolkit
* 和 Component 类创建的 Image 对象,并释放所有本地资源。
* 稍后可在呈现这些对象时根据需要从初始源重新加载它们,就像第一次创建它们时那样。
* */
bufferedImage.flush();
String filepath = "D:/draw.jpeg";
File imgfile = new File(filepath);
FileOutputStream fos;
try{
fos = new FileOutputStream(imgfile);
BufferedOutputStream bos = new BufferedOutputStream(fos);
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
encoder.encode(bufferedImage);
bos.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
draw();
}
}