发信人: Single_Fox (一狐),原信区: ustcbbs
标 题: 将canvas里头的图画保存成为gif或jpg图象,how
发信站: 中国科大BBS站 (Sun, 25 Apr 1999 12:34:27),站内信件
BBS水木清华站∶精华区
发信人: henrywang (海盗), 信区: Java, 读者数: 10
标 题: Re: 我想将canvas里头的图画保存成为gif或jpg图象,how
发信站: BBS 水木清华站 (Sun Jan 10 09:00:22 1999)
【 在 weffen (John) 的大作中提到: 】
∶ 有没有这样的库?
∶ 或者怎样实现?
给你一个存成bmp的类,至于jpg和gif照此琢磨着玩吧
package testPrint;
import java.awt.*;
import java.io.*;
import java.awt.image.*;
public class BMPFile extends Component {
//--- Private constants
private final static int BITMAPFILEHEADER_SIZE = 14;
private final static int BITMAPINFOHEADER_SIZE = 40;
//--- Private variable declaration
//--- Bitmap file header
private byte bitmapFileHeader [] = new byte [14];
private byte bfType [] = {'B', 'M'};
private int bfSize = 0;
private int bfReserved1 = 0;
private int bfReserved2 = 0;
private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE;
//--- Bitmap info header
private byte bitmapInfoHeader [] = new byte [40];
private int biSize = BITMAPINFOHEADER_SIZE;
private int biWidth = 0;
private int biHeight = 0;
private int biPlanes = 1;
private int biBitCount = 24;
private int biCompression = 0;
private int biSizeImage = 0x030000;
private int biXPelsPerMeter = 0x0;
private int biYPelsPerMeter = 0x0;
private int biClrUsed = 0;
private int biClrImportant = 0;
//--- Bitmap raw data
private int bitmap [];
//--- File section
private FileOutputStream fo;
//--- Default constructor
public BMPFile() {
}
public void saveBitmap (String parFilename, Image parImage, int
parWidth, int parHeight) {
try {
fo = new FileOutputStream (parFilename);
save (parImage, parWidth, parHeight);
fo.close ();
}
catch (Exception saveEx) {
saveEx.printStackTrace ();
}
}
/*
* The saveMethod is the main method of the process. This method
* will call the convertImage method to convert the memory image to
* a byte array; method writeBitmapFileHeader creates and writes
* the bitmap file header; writeBitmapInfoHeader creates the
* information header; and writeBitmap writes the image.
*
*/
private void save (Image parImage, int parWidth, int parHeight) {
try {
convertImage (parImage, parWidth, parHeight);
writeBitmapFileHeader ();
writeBitmapInfoHeader ();
writeBitmap ();
}
catch (Exception saveEx) {
saveEx.printStackTrace ();
}
}
/*
* convertImage converts the memory image to the bitmap format (BRG).
* It also computes some information for the bitmap info header.
*
*/
private boolean convertImage (Image parImage, int parWidth, int parHeight) {
int pad;
bitmap = new int [parWidth * parHeight];
PixelGrabber pg = new PixelGrabber (parImage, 0, 0, parWidth, parHeight,
bitmap, 0, parWidth);
try {
pg.grabPixels ();
}
catch (InterruptedException e) {
e.printStackTrace ();
return (false);
}
pad = (parWidth * 3) % 4;
if (pad != 0)
pad = (4 - pad) * parHeight;
biSizeImage = ((parWidth * parHeight) * 3) + pad;
bfSize = biSizeImage + BITMAPFILEHEADER_SIZE +
BITMAPINFOHEADER_SIZE;
biWidth = parWidth;
biHeight = parHeight;
return (true);
}
/*
* writeBitmap converts the image returned from the pixel grabber to
* the format required. Remember: scan lines are inverted in
* a bitmap file!
*
* Each scan line must be padded to an even 4-byte boundary.
*/
private void writeBitmap () {
int size;
int value;
int j;
int i;
int rowCount;
int rowIndex;
int lastRowIndex;
int pad;
int padCount;
byte rgb [] = new byte [3];
// if a scanline is not time of 4, add some bytes
size = (biWidth * biHeight) - 1;
pad = ((biWidth * 3) % 4);
if (pad != 0)
pad = 4 - pad;
rowCount = 1;
padCount = 0;
rowIndex = size - biWidth;
lastRowIndex = rowIndex;
try {
for (j = 0; j < size; j++) {
value = bitmap [rowIndex];
rgb [0] = (byte) (value & 0xFF);
rgb [1] = (byte) ((value >> 8) & 0xFF);
rgb [2] = (byte) ((value >> 16) & 0xFF);
fo.write (rgb);
if (rowCount == biWidth) {
padCount += pad;
for (i = 1; i <= pad; i++)
fo.write (0x00);
rowCount = 1;
rowIndex = lastRowIndex - biWidth;
lastRowIndex = rowIndex;
}
else
rowCount++;
rowIndex++;
}
//--- Update the size of the file
bfSize += padCount - pad;
biSizeImage += padCount - pad;
}
catch (Exception wb) {
wb.printStackTrace ();
}
}
/*
* writeBitmapFileHeader writes the bitmap file header to the file.
*
*/
private void writeBitmapFileHeader () {
try {
fo.write (bfType);
fo.write (intToDWord (bfSize));
fo.write (intToWord (bfReserved1));
fo.write (intToWord (bfReserved2));
fo.write (intToDWord (bfOffBits));
}
catch (Exception wbfh) {
wbfh.printStackTrace ();
}
}
/*
*
* writeBitmapInfoHeader writes the bitmap information header
* to the file.
*
*/
private void writeBitmapInfoHeader () {
try {
fo.write (intToDWord (biSize));
fo.write (intToDWord (biWidth));
fo.write (intToDWord (biHeight));
fo.write (intToWord (biPlanes));
fo.write (intToWord (biBitCount));
fo.write (intToDWord (biCompression));
fo.write (intToDWord (biSizeImage));
fo.write (intToDWord (biXPelsPerMeter));
fo.write (intToDWord (biYPelsPerMeter));
fo.write (intToDWord (biClrUsed));
fo.write (intToDWord (biClrImportant));
}
catch (Exception wbih) {
wbih.printStackTrace ();
}
}
/*
*
* intToWord converts an int to a word, where the return
* value is stored in a 2-byte array.
*
*/
private byte [] intToWord (int parValue) {
byte retValue [] = new byte [2];
retValue [0] = (byte) (parValue & 0x00FF);
retValue [1] = (byte) ((parValue >> 8) & 0x00FF);
return (retValue);
}
/*
*
* intToDWord converts an int to a double word, where the return
* value is stored in a 4-byte array.
*
*/
private byte [] intToDWord (int parValue) {
byte retValue [] = new byte [4];
retValue [0] = (byte) (parValue & 0x00FF);
retValue [1] = (byte) ((parValue >> 8) & 0x000000FF);
retValue [2] = (byte) ((parValue >> 16) & 0x000000FF);
retValue [3] = (byte) ((parValue >> 24) & 0x000000FF);
return (retValue);
}
}
在JPanel等JComponent上绘制的图象保存方法我已经知道 但是用同样的方法无法保存Canvas或Applet上作的图 --------------------------------------------------------------- import java.awt.*; import java.io.*; import javax.swing.*; import javax.imageio.*; import java.awt.image.*; import java.awt.event.*; import java.awt.color.*; import java.util.*; import javax.imageio.stream.*; public class SaveCanvas extends Frame { ImageCanvas ic = new ImageCanvas(); public SaveCanvas() { Button b=new Button("save canvas"); b.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { Iterator writers = ImageIO.getImageWritersByFormatName("jpeg"); ImageWriter writer = (ImageWriter)writers.next(); ImageOutputStream ios = null; BufferedImage bufferedImage=new BufferedImage(ic.getWidth(),ic.getHeight(),BufferedImage.TYPE_INT_RGB); Graphics g = bufferedImage.getGraphics(); ic.paint(g); g.dispose(); try{ ios = ImageIO.createImageOutputStream(new FileOutputStream("myPicture.jpg"));} catch(IOException ioe){} writer.setOutput(ios); try{ writer.write(bufferedImage);} catch(IOException ioe){} } }); setLayout(new BorderLayout()); add(b,BorderLayout.NORTH); add(ic,BorderLayout.CENTER); setSize(new Dimension(400,400)); setVisible(true); } public static void main(String args[]) { new SaveCanvas(); } class ImageCanvas extends Canvas { public void paint(Graphics g) { g.setColor(Color.blue); g.fillRect(0,0,this.getWidth(),this.getHeight()); g.setColor(Color.red); g.drawLine(0,0,this.getWidth(),this.getHeight()); } } } --------------------------------------------------------------- jdk1.3的方法 //父类 import javax.swing.JComponent; import java.io.OutputStream; /** @author Turbo Chen * @version 1.0 */ public abstract class ImageWriter { public abstract void write(JComponent comp, OutputStream out) throws Exception; } // 保存为jpg图片的类 import com.sun.image.codec.jpeg.*; import java.io.OutputStream; import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.JComponent; public class JPGWriter extends ImageWriter { public void write(JComponent myComponent, OutputStream out) throws Exception { int imgWidth = (int)myComponent.getSize().getWidth(), imgHeight = (int)myComponent.getSize().getHeight(); Dimension size = new Dimension(imgWidth,imgHeight); BufferedImage myImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB); Graphics2D g2 = myImage.createGraphics(); myComponent.paint(g2); try { JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); encoder.encode(myImage); out.close(); } catch (Exception e) { throw new Exception("GRAPHICS ERROR,CANNOT CREATE JPEG FORMAT"); } } } ------------------------ //保存为bmp图片的类 import java.awt.*; import java.awt.image.*; import java.io.*; import javax.swing.*; public class BMPWriter extends ImageWriter { //--- Private constants private final static int BITMAPFILEHEADER_SIZE = 14; private final static int BITMAPINFOHEADER_SIZE = 40; //--- Private variable declaration //--- Bitmap file header private byte bitmapFileHeader [] = new byte [BITMAPFILEHEADER_SIZE]; private byte bfType [] = {'B', 'M'}; private int bfSize = 0; private int bfReserved1 = 0; private int bfReserved2 = 0; private int bfOffBits = BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE; //--- Bitmap info header private byte bitmapInfoHeader [] = new byte [BITMAPINFOHEADER_SIZE]; private int biSize = BITMAPINFOHEADER_SIZE; private int biWidth = 0; private int biHeight = 0; private int biPlanes = 1; private int biBitCount = 24; private int biCompression = 0; private int biSizeImage = 0x030000; private int biXPelsPerMeter = 0x0; private int biYPelsPerMeter = 0x0; private int biClrUsed = 0; private int biClrImportant = 0; //--- Bitmap raw data private int bitmap []; //--- File section private OutputStream fo; //--- Default constructor public void write (JComponent comp, OutputStream out) throws Exception { try { fo = out; int w = comp.getSize().width; int h = comp.getSize().height; Image image = comp.createImage(w, h); Graphics g = image.getGraphics(); comp.paint(g); save (image, w, h); out.close (); } catch (Exception saveEx) { throw new Exception("GRAPHICS ERROR,CAN NOT CREATE BMP FORMAT"); } } /** * The saveMethod is the main method of the process. This method * will call the convertImage method to convert the memory image to * a byte array; method writeBitmapFileHeader creates and writes * the bitmap file header; writeBitmapInfoHeader creates the * information header; and writeBitmap writes the image. * */ private void save (Image parImage, int parWidth, int parHeight) throws Exception { convertImage (parImage, parWidth, parHeight); writeBitmapFileHeader (); writeBitmapInfoHeader (); writeBitmap (); } /** * convertImage converts the memory image to the bitmap format (RGB). * It also computes some information for the bitmap info header. * * @param parImage * @param parWidth * @param parHeight * @return */ private boolean convertImage (Image parImage, int parWidth, int parHeight) { int pad; bitmap = new int [parWidth * parHeight]; PixelGrabber pg = new PixelGrabber (parImage, 0, 0, parWidth, parHeight, bitmap, 0, parWidth); try { pg.grabPixels (); } catch (InterruptedException e) { return (false); } pad = (4 - ((parWidth * 3) % 4)) * parHeight; biSizeImage = ((parWidth * parHeight) * 3) + pad; bfSize = biSizeImage + BITMAPFILEHEADER_SIZE + BITMAPINFOHEADER_SIZE; biWidth = parWidth; biHeight = parHeight; return (true); } /** * writeBitmap converts the image returned from the pixel grabber to * the format required. Remember: scan lines are inverted in * a bitmap file! * * Each scan line must be padded to an even 4-byte boundary. */ private void writeBitmap () throws Exception { int size; int value; int j; int i; int rowCount; int rowIndex; int lastRowIndex; int pad; int padCount; byte rgb [] = new byte [3]; size = (biWidth * biHeight) - 1; pad = 4 - ((biWidth * 3) % 4); if (pad == 4) // <==== Bug correction pad = 0; // <==== Bug correction rowCount = 1; padCount = 0; rowIndex = size - biWidth; lastRowIndex = rowIndex; for (j = 0; j < size; j++) { value = bitmap [rowIndex]; rgb [0] = (byte) (value & 0xFF); rgb [1] = (byte) ((value >> 8) & 0xFF); rgb [2] = (byte) ((value >> 16) & 0xFF); fo.write (rgb); if (rowCount == biWidth) { padCount += pad; for (i = 1; i <= pad; i++) { fo.write (0x00); } rowCount = 1; rowIndex = lastRowIndex - biWidth; lastRowIndex = rowIndex; } else rowCount++; rowIndex++; } //--- Update the size of the file bfSize += padCount - pad; biSizeImage += padCount - pad; } /** * writeBitmapFileHeader writes the bitmap file header to the file. * */ private void writeBitmapFileHeader () throws Exception { fo.write (bfType); fo.write (intToDWord (bfSize)); fo.write (intToWord (bfReserved1)); fo.write (intToWord (bfReserved2)); fo.write (intToDWord (bfOffBits)); } /** * * writeBitmapInfoHeader writes the bitmap information header * to the file. * */ private void writeBitmapInfoHeader () throws Exception { fo.write (intToDWord (biSize)); fo.write (intToDWord (biWidth)); fo.write (intToDWord (biHeight)); fo.write (intToWord (biPlanes)); fo.write (intToWord (biBitCount)); fo.write (intToDWord (biCompression)); fo.write (intToDWord (biSizeImage)); fo.write (intToDWord (biXPelsPerMeter)); fo.write (intToDWord (biYPelsPerMeter)); fo.write (intToDWord (biClrUsed)); fo.write (intToDWord (biClrImportant)); } /** * * intToWord converts an int to a word, where the return * value is stored in a 2-byte array. * */ private byte [] intToWord (int parValue) { byte retValue [] = new byte [2]; retValue [0] = (byte) (parValue & 0x00FF); retValue [1] = (byte) ((parValue >> 8) & 0x00FF); return (retValue); } /** * * intToDWord converts an int to a double word, where the return * value is stored in a 4-byte array. * */ private byte [] intToDWord (int parValue) { byte retValue [] = new byte [4]; retValue [0] = (byte) (parValue & 0x00FF); retValue [1] = (byte) ((parValue >> 8) & 0x000000FF); retValue [2] = (byte) ((parValue >> 16) & 0x000000FF); retValue [3] = (byte) ((parValue >> 24) & 0x000000FF); return (retValue); } } 将上面三个类保存为相应的java文件,使用时,只要告诉它图形所在的Componetn和输出文件就可以了。 ---------------------------------------- 例如: ImageWriter writer = new JPGWriter(xxxComp, new FileOutputStream("c://test.jpg")); writer.write(); xxxComp是你画好的图形所在的JComponent组件,如JPanel等,一般画图都是在JPanel或是JComponent上画的。 |
--
※ 来源: 中国科大BBS站 [bbs.ustc.edu.cn]