java image

ImageIcon 发表评论(0) 编辑词条

import   java.io.*;
import   java.util.*;
import   com.sun.image.codec.jpeg.*;
import   java.awt.*;
import   java.awt.geom.*;
import   java.awt.image.*;

FileOutputStream   out=new   FileOutputStream( "a.jpeg ");
BufferedImage   image=new   BufferedImage(150,100,BufferedImage.TYPE_INT_RGB);
JPEGImageEncoder   encoder=JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();

 

 

 

import   java.io.*;
import   java.util.*;
import   com.sun.image.codec.jpeg.*;
import   java.awt.*;
import   java.awt.geom.*;
import   java.awt.image.*;

FileOutputStream   out=new   FileOutputStream( "a.jpeg ");
BufferedImage   image=new   BufferedImage(150,100,BufferedImage.TYPE_INT_RGB);
JPEGImageEncoder   encoder=JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
out.close();
jdk1.2就有

 

 

 

 

javax.swing
类 ImageIcon

java.lang.Object  
javax.swing.ImageIcon
所有已实现的接口:
Serializable, Accessible, Icon

public class ImageIcon
extends Objectimplements Icon, Serializable, Accessible
 

一个 Icon 接口的实现,它根据 Image 绘制 Icon。可使用 MediaTracker 预载根据 URL、文件名或字节数组创建的图像,以监视该图像的加载状态。

有关使用图像图标的更多信息和示例,请参阅《The Java Tutorial》中的 How to Use Icons 一节。

警告:此类的序列化对象与以后的 Swing 版本不兼容。当前序列化支持适用于短期存储,或适用于在运行相同 Swing 版本的应用程序之间进行 RMI(Remote Method Invocation,远程方法调用)。从 1.4 版本开始,已在 java.beans 包中添加了支持所有 JavaBeansTM 长期存储的功能。请参见 XMLEncoder

 

 


嵌套类摘要
protected  class ImageIcon.AccessibleImageIcon
          此类实现 ImageIcon 类的可访问性支持。
 
字段摘要
protected static Component component
           
protected static MediaTracker tracker
           
 
构造方法摘要
ImageIcon()
          创建一个未初始化的图像图标。
ImageIcon(byte[] imageData)
          根据字节数组创建一个 ImageIcon,这些字节读取自一个包含受支持图像格式(比如 GIF、JPEG 或从 1.3 版本开始的 PNG)的图像文件。
ImageIcon(byte[] imageData, String description)
          根据字节数组创建一个 ImageIcon,这些字节读取自一个包含受支持图像格式(比如 GIF、JPEG 或从 1.3 版本开始的 PNG)的图像文件。
ImageIcon(Image image)
          根据图像对象创建一个 ImageIcon。
ImageIcon(Image image, String description)
          根据图像创建一个 ImageIcon。
ImageIcon(String filename)
          根据指定的文件创建一个 ImageIcon。
ImageIcon(String filename, String description)
          根据指定的文件创建一个 ImageIcon。
ImageIcon(URL location)
          根据指定的 URL 创建一个 ImageIcon。
ImageIcon(URL location, String description)
          根据指定的 URL 创建一个 ImageIcon。
 
方法摘要
 AccessibleContext getAccessibleContext()
          获得与此 ImageIcon 关联的 AccessibleContext。
 String getDescription()
          获得图像的描述。
 int getIconHeight()
          获得图标的高度。
 int getIconWidth()
          获得图标的宽度。
 Image getImage()
          返回此图标的 Image
 int getImageLoadStatus()
          返回图像加载操作的状态。
 ImageObserver getImageObserver()
          返回图像的图像观察者。
protected  void loadImage(Image image)
          加载图像,并且只在图像已加载时返回。
 void paintIcon(Component c, Graphics g, int x, int y)
          绘制图标。
 void setDescription(String description)
          设置图像的描述。
 void setImage(Image image)
          设置由此图标显示的图像。
 void setImageObserver(ImageObserver observer)
          设置图像的图像观察者。
 String toString()
          返回此图像的字符串表示形式。
 
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

字段详细信息

component

protected static final Component component

tracker

protected static final MediaTracker tracker
构造方法详细信息

ImageIcon

public ImageIcon(String filename,                 String description)
根据指定的文件创建一个 ImageIcon。使用 MediaTracker 预载图像以监视图像的加载状态。

 

参数:
filename - 包含图像的文件的名称
description - 图像的简明文本描述
另请参见:
ImageIcon(String)

ImageIcon

public ImageIcon(String filename)
根据指定的文件创建一个 ImageIcon。使用 MediaTracker 预载图像以监视图像的加载状态。指定 String 可以是一个文件名或是一条文件路径。在指定一条路径时,可使用 Internet 标准正斜杠 ("/") 作为分隔符。(该字符串被转换成一个 URL,而正斜杠适用于所有系统。)例如,指定:
    new ImageIcon("images/myImage.gif") 
该描述被初始化为 filename 字符串。

 

参数:
filename - 指定文件名或路径的 String
另请参见:
getDescription()

ImageIcon

public ImageIcon(URL location,                 String description)
根据指定的 URL 创建一个 ImageIcon。使用 MediaTracker 预载图像以监视图像的加载状态。

 

参数:
location - 图像的 URL
description - 图像的简明文本描述
另请参见:
ImageIcon(String)

ImageIcon

public ImageIcon(URL location)
根据指定的 URL 创建一个 ImageIcon。使用 MediaTracker 预载图像以监视图像的加载状态。图标的描述被初始化为 URL 的字符串表示形式。

 

参数:
location - 图像的 URL
另请参见:
getDescription()

ImageIcon

public ImageIcon(Image image,                 String description)
根据图像创建一个 ImageIcon。

 

参数:
image - 图像
description - 图像的简明文本描述

ImageIcon

public ImageIcon(Image image)
根据图像对象创建一个 ImageIcon。如果图像有一个字符串形式的 "comment" 属性,则该字符串被用作此图标的描述。

 

参数:
image - 图像
另请参见:
getDescription(), Image.getProperty(java.lang.String, java.awt.image.ImageObserver)

ImageIcon

public ImageIcon(byte[] imageData,                 String description)
根据字节数组创建一个 ImageIcon,这些字节读取自一个包含受支持图像格式(比如 GIF、JPEG 或从 1.3 版本开始的 PNG)的图像文件。通常,此数组是通过使用 Class.getResourceAsStream() 读取图像文件来创建的,但该字节数组也可以静态地存储在某个类中。

 

参数:
imageData - 一个像素数组,具有受 AWT Toolkit 支持的图像格式,比如 GIF、JPEG 或从 1.3 版本开始的 PNG
description - 图像的简明文本描述
另请参见:
Toolkit.createImage(java.lang.String)

ImageIcon

public ImageIcon(byte[] imageData)
根据字节数组创建一个 ImageIcon,这些字节读取自一个包含受支持图像格式(比如 GIF、JPEG 或从 1.3 版本开始的 PNG)的图像文件。通常,此数组是通过使用 Class.getResourceAsStream() 读取一幅图像来创建的,但该字节数组也可以静态地存储在某个类中。如果得到的图像有一个字符串形式的 "comment" 属性,则该字符串被用作此图标的描述。

 

参数:
imageData - 一个像素数组,具有受 AWT Toolkit 支持的图像格式,比如 GIF、JPEG 或从 1.3 版本开始的 PNG
另请参见:
Toolkit.createImage(java.lang.String), getDescription(), Image.getProperty(java.lang.String, java.awt.image.ImageObserver)

ImageIcon

public ImageIcon()
创建一个未初始化的图像图标。

 

方法详细信息

loadImage

protected void loadImage(Image image)
加载图像,并且只在图像已加载时返回。

 

参数:
image - 图像

getImageLoadStatus

public int getImageLoadStatus()
返回图像加载操作的状态。

 

返回:
由 java.awt.MediaTracker 定义的加载状态
另请参见:
MediaTracker.ABORTED, MediaTracker.ERRORED, MediaTracker.COMPLETE

getImage

public Image getImage()
返回此图标的 Image

 

返回:
ImageIconImage 对象

setImage

public void setImage(Image image)
设置由此图标显示的图像。

 

参数:
image - 图像

getDescription

public String getDescription()
获得图像的描述。此描述应该是该对象的简明文本描述。例如,可以将它呈现给盲人用户,为他们提供该图像用途的指示。该描述可以为 null。

 

返回:
图像的简明文本描述。

setDescription

public void setDescription(String description)
设置图像的描述。此描述应该是该对象的简明文本描述。例如,可以将它呈现给盲人用户,为他们提供该图像用途的指示。

 

参数:
description - 图像的简明文本描述。

paintIcon

public void paintIcon(Component c,                      Graphics g,                      int x,                      int y)
绘制图标。图标的左上角在图形上下文 g 的座标空间中的点 (x, y) 处绘制。如果此图标没有图像观察者,则此方法使用 c 组件作为观察者。

 

指定者:
接口 Icon 中的 paintIcon
参数:
c - 用作观察者的组件,如果此图标没有图像观察者
g - 图形上下文
x - 图标左上角的 X 座标
y - 图标左上角的 Y 座标

getIconWidth

public int getIconWidth()
获得图标的宽度。

 

指定者:
接口 Icon 中的 getIconWidth
返回:
此图标的宽度,以像素为单位

getIconHeight

public int getIconHeight()
获得图标的高度。

 

指定者:
接口 Icon 中的 getIconHeight
返回:
此图标的高度,以像素为单位

setImageObserver

public void setImageObserver(ImageObserver observer)
设置图像的图像观察者。如果 ImageIcon 包含一个动画 GIF,则设置此属性,而观察者获得更新其显示的通知。例如:
     icon = new ImageIcon(...)     button.setIcon(icon);     icon.setImageObserver(button); 

 

参数:
observer - 图像观察者

getImageObserver

public ImageObserver getImageObserver()
返回图像的图像观察者。

 

返回:
图像观察者,它可以为 null

toString

public String toString()
返回此图像的字符串表示形式。

 

覆盖:
Object 中的 toString
返回:
表示此图像的字符串

getAccessibleContext

public AccessibleContext getAccessibleContext()
获得与此 ImageIcon 关联的 AccessibleContext。对于图像图标,AccessibleContext 采用 AccessibleImageIcon 的形式。如有必要,可创建一个新的 AccessibleImageIcon 实例。

 

指定者:
接口 Accessible 中的 getAccessibleContext
返回:
一个 AccessibleImageIcon,它将充当此 ImageIcon 的 AccessibleContext

将Java image对象转换成PNG格式字节数组

 
发布时间:2006.04.26 15:32     来源:天新网    作者:




/**
 

* PngEncoder takes a Java Image object and creates a byte string which can be saved as a PNG file.
 

* The Image is presumed to use the DirectColorModel.
 

*
 

* Thanks to Jay Denny at KeyPoint Software
 

* http://www.keypoint.com/
 

* who let me develop this code on company time.
 

*
 

* You may contact me with (probably very-much-needed) improvements,
 

* comments, and bug fixes at:
 

*
 

* [email protected]
 

*
 

* This library is free software; you can redistribute it and/or
 

* modify it under the terms of the GNU Lesser General Public
 

* License as published by the Free Software Foundation; either
 

* version 2.1 of the License, or (at your option) any later version.
 

*
 

* This library is distributed in the hope that it will be useful,
 

* but WITHOUT ANY WARRANTY; without even the implied warranty of
 

* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 

* Lesser General Public License for more details.
 

*
 

* You should have received a copy of the GNU Lesser General Public
 

* License along with this library; if not, write to the Free Software
 

* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 

* A copy of the GNU LGPL may be found at
 

* http://www.gnu.org/copyleft/lesser.html,
 

*
 

* @author J. David Eisenberg
 

* @version 1.4, 31 March 2000
 

*/
 


 

import java.awt.*;
 

import java.awt.image.*;
 

import java.util.*;
 

import java.util.zip.*;
 

import java.io.*;
 


 

public class PngEncoder extends Object
 

{
 

/** Constant specifying that alpha channel should be encoded. */
 

public static final boolean ENCODE_ALPHA=true;
 

/** Constant specifying that alpha channel should not be encoded. */
 

public static final boolean NO_ALPHA=false;
 

/** Constants for filters */
 

public static final int FILTER_NONE = 0;
 

public static final int FILTER_SUB = 1;
 

public static final int FILTER_UP = 2;
 

public static final int FILTER_LAST = 2;
 


 

protected byte[] pngBytes;
 

protected byte[] priorRow;
 

protected byte[] leftBytes;
 

protected Image image;
 

protected int width, height;
 

protected int bytePos, maxPos;
 

protected int hdrPos, dataPos, endPos;
 

protected CRC32 crc = new CRC32();
 

protected long crcValue;
 

protected boolean encodeAlpha;
 

protected int filter;
 

protected int bytesPERPixel;
 

protected int compressionLevel;
 


 

/**
 

* Class constructor
 

*
 

*/
 

public PngEncoder()
 

{
 

this( null, false, FILTER_NONE, 0 );
 

}
 


 

/**
 

* Class constructor specifying Image to encode, with no alpha channel encoding.
 

*
 

* @param image A Java Image object which uses the DirectColorModel
 

* @see java.awt.Image
 

*/
 

public PngEncoder( Image image )
 

{
 

this(image, false, FILTER_NONE, 0);
 

}
 


 

/**
 

* Class constructor specifying Image to encode, and whether to encode alpha.
 

*
 

* @param image A Java Image object which uses the DirectColorModel
 

* @param encodeAlpha Encode the alpha channel? false=no; true=yes
 

* @see java.awt.Image
 

*/
 

public PngEncoder( Image image, boolean encodeAlpha )
 

{
 

this(image, encodeAlpha, FILTER_NONE, 0);
 

}
 


 

/**
 

* Class constructor specifying Image to encode, whether to encode alpha, and filter to use.
 

*
 

* @param image A Java Image object which uses the DirectColorModel
 

* @param encodeAlpha Encode the alpha channel? false=no; true=yes
 

* @param whichFilter 0=none, 1=sub, 2=up
 

* @see java.awt.Image
 

*/
 

public PngEncoder( Image image, boolean encodeAlpha, int whichFilter )
 

{
 

this( image, encodeAlpha, whichFilter, 0 );
 

}
 


 


 

/**
 

* Class constructor specifying Image source to encode, whether to encode alpha, filter to use, and compression level.
 

*
 

* @param image A Java Image object
 

* @param encodeAlpha Encode the alpha channel? false=no; true=yes
 

* @param whichFilter 0=none, 1=sub, 2=up
 

* @param compLevel 0..9
 

* @see java.awt.Image
 

*/
 

public PngEncoder( Image image, boolean encodeAlpha, int whichFilter,
 

int compLevel)
 

{
 

this.image = image;
 

this.encodeAlpha = encodeAlpha;
 

setFilter( whichFilter );
 

if (compLevel >=0 && compLevel <=9)
 

{
 

this.compressionLevel = compLevel;
 

}
 

}
 


 

/**
 

* Set the image to be encoded
 

*
 

* @param image A Java Image object which uses the DirectColorModel
 

* @see java.awt.Image
 

* @see java.awt.image.DirectColorModel
 

*/
 

public void setImage( Image image )
 

{
 

this.image = image;
 

pngBytes = null;
 

}
 


 

/**
 

* Creates an array of bytes that is the PNG equivalent of the current image, specifying whether to encode alpha or not.
 

*
 

* @param encodeAlpha boolean false=no alpha, true=encode alpha
 

* @return an array of bytes, or null if there was a problem
 

*/
 

public byte[] pngEncode( boolean encodeAlpha )
 

{
 

byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
 

int i;
 


 

if (image == null)
 

{
 

return null;
 

}
 

width = image.getWidth( null );
 

height = image.getHeight( null );
 

this.image = image;
 


 

/*
 

* start with an array that is big enough to hold all the pixels
 

* (plus filter bytes), and an extra 200 bytes for header info
 

*/
 

pngBytes = new byte[((width+1) * height * 3) + 200];
 


 

/*
 

* keep track of largest byte written to the array
 

*/
 

maxPos = 0;
 


 

bytePos = writeBytes( pngIdBytes, 0 );
 

hdrPos = bytePos;
 

writeHeader();
 

dataPos = bytePos;
 

if (writeImageData())
 

{
 

writeEnd();
 

pngBytes = resizeByteArray( pngBytes, maxPos );
 

}
 

else
 

{
 

pngBytes = null;
 

}
 

return pngBytes;
 

}
 


 

/**
 

* Creates an array of bytes that is the PNG equivalent of the current image.
 

* Alpha encoding is determined by its setting in the constructor.
 

*
 

* @return an array of bytes, or null if there was a problem
 

*/
 

public byte[] pngEncode()
 

{
 

return pngEncode( encodeAlpha );
 

}
 


 

/**
 

* Set the alpha encoding on or off.
 

*
 

* @param encodeAlpha false=no, true=yes
 

*/
 

public void setEncodeAlpha( boolean encodeAlpha )
 

{
 

this.encodeAlpha = encodeAlpha;
 

}
 


 

/**
 

* Retrieve alpha encoding status.
 

*
 

* @return boolean false=no, true=yes
 

*/
 

public boolean getEncodeAlpha()
 

{
 

return encodeAlpha;
 

}
 


 

/**
 

* Set the filter to use
 

*
 

* @param whichFilter from constant list
 

*/
 

public void setFilter( int whichFilter )
 

{
 

this.filter = FILTER_NONE;
 

if ( whichFilter <= FILTER_LAST )
 

{
 

this.filter = whichFilter;
 

}
 

}
 


 

/**
 

* Retrieve filtering scheme
 

*
 

* @return int (see constant list)
 

*/
 

public int getFilter()
 

{
 

return filter;
 

}
 


 

/**
 

* Set the compression level to use
 

*
 

* @param level 0 through 9
 

*/
 

public void setCompressionLevel( int level )
 

{
 

if ( level >= 0 && level <= 9)
 

{
 

this.compressionLevel = level;
 

}
 

}
 


 

/**
 

* Retrieve compression level
 

*
 

* @return int in range 0-9
 

*/
 

public int getCompressionLevel()
 

{
 

return compressionLevel;
 

}
 


 

/**
 

* Increase or decrease the length of a byte array.
 

*
 

* @param array The original array.
 

* @param newLength The length you wish the new array to have.
 

* @return Array of newly desired length. If shorter than the
 

* original, the trailing elements are truncated.
 

*/
 

protected byte[] resizeByteArray( byte[] array, int newLength )
 

{
 

byte[] newArray = new byte[newLength];
 

int oldLength = array.length;
 


 

System.arraycopy( array, 0, newArray, 0,
 

Math.min( oldLength, newLength ) );
 

return newArray;
 

}
 


 

/**
 

* Write an array of bytes into the pngBytes array.
 

* Note: This routine has the side effect of updating
 

* maxPos, the largest element written in the array.
 

* The array is resized by 1000 bytes or the length
 

* of the data to be written, whichever is larger.
 

*
 

* @param data The data to be written into pngBytes.
 

* @param offset The starting point to write to.
 

* @return The next place to be written to in the pngBytes array.
 

*/
 

protected int writeBytes( byte[] data, int offset )
 

{
 

maxPos = Math.max( maxPos, offset + data.length );
 

if (data.length + offset > pngBytes.length)
 

{
 

pngBytes = resizeByteArray( pngBytes, pngBytes.length +
 

Math.max( 1000, data.length ) );
 

}
 

System.arraycopy( data, 0, pngBytes, offset, data.length );
 

return offset + data.length;
 

}
 


 

/**
 

* Write an array of bytes into the pngBytes array, specifying number of bytes to write.
 

* Note: This routine has the side effect of updating
 

* maxPos, the largest element written in the array.
 

* The array is resized by 1000 bytes or the length
 

* of the data to be written, whichever is larger.
 

*
 

* @param data The data to be written into pngBytes.
 

* @param nBytes The number of bytes to be written.
 

* @param offset The starting point to write to.
 

* @return The next place to be written to in the pngBytes array.
 

*/
 

protected int writeBytes( byte[] data, int nBytes, int offset )
 

{
 

maxPos = Math.max( maxPos, offset + nBytes );
 

if (nBytes + offset > pngBytes.length)
 

{
 

pngBytes = resizeByteArray( pngBytes, pngBytes.length +
 

Math.max( 1000, nBytes ) );
 

}
 

System.arraycopy( data, 0, pngBytes, offset, nBytes );
 

return offset + nBytes;
 

}
 


 

/**
 

* Write a two-byte integer into the pngBytes array at a given position.
 

*
 

* @param n The integer to be written into pngBytes.
 

* @param offset The starting point to write to.
 

* @return The next place to be written to in the pngBytes array.
 

*/
 

protected int writeInt2( int n, int offset )
 

{
 

byte[] temp = { (byte)((n >> 8) & 0xff),
 

(byte) (n & 0xff) };
 

return writeBytes( temp, offset );
 

}
 


 

/**
 

* Write a four-byte integer into the pngBytes array at a given position.
 

*
 

* @param n The integer to be written into pngBytes.
 

* @param offset The starting point to write to.
 

* @return The next place to be written to in the pngBytes array.
 

*/
 

protected int writeInt4( int n, int offset )
 

{
 

byte[] temp = { (byte)((n >> 24) & 0xff),
 

(byte) ((n >> 16) & 0xff ),
 

(byte) ((n >> 8) & 0xff ),
 

(byte) ( n & 0xff ) };
 

return writeBytes( temp, offset );
 

}
 


 

/**
 

* Write a single byte into the pngBytes array at a given position.
 

*
 

* @param n The integer to be written into pngBytes.
 

* @param offset The starting point to write to.
 

* @return The next place to be written to in the pngBytes array.
 

*/
 

protected int writeByte( int b, int offset )
 

{
 

byte[] temp = { (byte) b };
 

return writeBytes( temp, offset );
 

}
 


 

/**
 

* Write a string into the pngBytes array at a given position.
 

* This uses the getBytes method, so the encoding used will
 

* be its default.
 

*
 

* @param n The integer to be written into pngBytes.
 

* @param offset The starting point to write to.
 

* @return The next place to be written to in the pngBytes array.
 

* @see java.lang.String#getBytes()
 

*/
 

protected int writeString( String s, int offset )
 

{
 

return writeBytes( s.getBytes(), offset );
 

}
 


 

/**
 

* Write a PNG "IHDR" chunk into the pngBytes array.
 

*/
 

protected void writeHeader()
 

{
 

int startPos;
 


 

startPos = bytePos = writeInt4( 13, bytePos );
 

bytePos = writeString( "IHDR", bytePos );
 

width = image.getWidth( null );
 

height = image.getHeight( null );
 

bytePos = writeInt4( width, bytePos );
 

bytePos = writeInt4( height, bytePos );
 

bytePos = writeByte( 8, bytePos ); // bit depth
 

bytePos = writeByte( (encodeAlpha) ? 6 : 2, bytePos ); // direct model
 

bytePos = writeByte( 0, bytePos ); // compression method
 

bytePos = writeByte( 0, bytePos ); // filter method
 

bytePos = writeByte( 0, bytePos ); // no interlace
 

crc.reset();
 

crc.update( pngBytes, startPos, bytePos-startPos );
 

crcValue = crc.getValue();
 

bytePos = writeInt4( (int) crcValue, bytePos );
 

}
 


 

/**
 

* Perform "sub" filtering on the given row.
 

* Uses temporary array leftBytes to store the original values
 

* of the previous pixels. The array is 16 bytes long, which
 

* will easily hold two-byte samples plus two-byte alpha.
 

*
 

* @param pixels The array holding the scan lines being built
 

* @param startPos Starting position within pixels of bytes to be filtered.
 

* @param width Width of a scanline in pixels.
 

*/
 

protected void filterSub( byte[] pixels, int startPos, int width )
 

{
 

int i;
 

int offset = bytesPerPixel;
 

int actualStart = startPos + offset;
 

int nBytes = width * bytesPerPixel;
 

int leftInsert = offset;
 

int leftExtract = 0;
 

byte current_byte;
 


 

for (i=actualStart; i < startPos + nBytes; i++)
 

{
 

leftBytes[leftInsert] = pixels[i];
 

pixels[i] = (byte) ((pixels[i] - leftBytes[leftExtract]) % 256);
 

leftInsert = (leftInsert+1) % 0x0f;
 

leftExtract = (leftExtract + 1) % 0x0f;
 

}
 

}
 


 

/**
 

* Perform "up" filtering on the given row.
 

* Side effect: refills the prior row with current row
 

*
 

* @param pixels The array holding the scan lines being built
 

* @param startPos Starting position within pixels of bytes to be filtered.
 

* @param width Width of a scanline in pixels.
 

*/
 

protected void filterUp( byte[] pixels, int startPos, int width )
 

{
 

int i, nBytes;
 

byte current_byte;
 


 

nBytes = width * bytesPerPixel;
 


 

for (i=0; i < nBytes; i++)
 

{
 

current_byte = pixels[startPos + i];
 

pixels[startPos + i] = (byte) ((pixels[startPos + i] - priorRow[i]) % 256);
 

priorRow[i] = current_byte;
 

}
 

}
 


 

/**
 

* Write the image data into the pngBytes array.
 

* This will write one or more PNG "IDAT" chunks. In order
 

* to conserve memory, this method grabs as many rows as will
 

* fit into 32K bytes, or the whole image; whichever is less.
 

*
 

*
 

* @return true if no errors; false if error grabbing pixels
 

*/
 

protected boolean writeImageData()
 

{
 

int rowsLeft = height; // number of rows remaining to write
 

int startRow = 0; // starting row to process this time through
 

int nRows; // how many rows to grab at a time
 


 

byte[] scanLines; // the scan lines to be compressed
 

int scanPos; // where we are in the scan lines
 

int startPos; // where this line's actual pixels start (used for filtering)
 


 

byte[] compressedLines; // the resultant compressed lines
 

int nCompressed; // how big is the compressed area?
 


 

int depth; // color depth ( handle only 8 or 32 )
 


 

PixelGrabber pg;
 


 

bytesPerPixel = (encodeAlpha) ? 4 : 3;
 


 

Deflater scrunch = new Deflater( compressionLevel );
 

ByteArrayOutputStream outBytes =
 

new ByteArrayOutputStream(1024);
 


 

DeflaterOutputStream comPBytes =
 

new DeflaterOutputStream( outBytes, scrunch );
 

try
 

{
 

while (rowsLeft > 0)
 

{
 

nRows = Math.min( 32767 / (width*(bytesPerPixel+1)), rowsLeft );
 

// nRows = rowsLeft;
 


 

int[] pixels = new int[width * nRows];
 


 

pg = new PixelGrabber(image, 0, startRow,
 

width, nRows, pixels, 0, width);
 

try {
 

pg.grabPixels();
 

}
 

catch (Exception e) {
 

System.err.println("interrupted waiting for pixels!");
 

return false;
 

}
 

if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
 

System.err.println("image fetch aborted or errored");
 

return false;
 

}
 


 

/*
 

* Create a data chunk. scanLines adds "nRows" for
 

* the filter bytes.
 

*/
 

scanLines = new byte[width * nRows * bytesPerPixel + nRows];
 


 

if (filter == FILTER_SUB)
 

{
 

leftBytes = new byte[16];
 

}
 

if (filter == FILTER_UP)
 

{
 

priorRow = new byte[width*bytesPerPixel];
 

}
 


 

scanPos = 0;
 

startPos = 1;
 

for (int i=0; i

{
 

if (i % width == 0)
 

{
 

scanLines[scanPos++] = (byte) filter;
 

startPos = scanPos;
 

}
 

scanLines[scanPos++] = (byte) ((pixels[i] >> 16) & 0xff);
 

scanLines[scanPos++] = (byte) ((pixels[i] >> 8) & 0xff);
 

scanLines[scanPos++] = (byte) ((pixels[i] ) & 0xff);
 

if (encodeAlpha)
 

{
 

scanLines[scanPos++] = (byte) ((pixels[i] >> 24) & 0xff );
 

}
 

if ((i % width == width-1) && (filter != FILTER_NONE))
 

{
 

if (filter == FILTER_SUB)
 

{
 

filterSub( scanLines, startPos, width );
 

}
 

if (filter == FILTER_UP)
 

{
 

filterUp( scanLines, startPos, width );
 

}
 

}
 

}
 


 

/*
 

* Write these lines to the output area
 

*/
 

compBytes.write( scanLines, 0, scanPos );
 


 


 

startRow += nRows;
 

rowsLeft -= nRows;
 

}
 

compBytes.close();
 


 

/*
 

* Write the compressed bytes
 

*/
 

compressedLines = outBytes.toByteArray();
 

nCompressed = compressedLines.length;
 


 

crc.reset();
 

bytePos = writeInt4( nCompressed, bytePos );
 

bytePos = writeString("IDAT", bytePos );
 

crc.update("IDAT".getBytes());
 

bytePos = writeBytes( compressedLines, nCompressed, bytePos );
 

crc.update( compressedLines, 0, nCompressed );
 


 

crcValue = crc.getValue();
 

bytePos = writeInt4( (int) crcValue, bytePos );
 

scrunch.finish();
 

return true;
 

}
 

catch (IOException e)
 

{
 

System.err.println( e.toString());
 

return false;
 

}
 

}
 


 

/**
 

* Write a PNG "IEND" chunk into the pngBytes array.
 

*/
 

protected void writeEnd()
 

{
 

bytePos = writeInt4( 0, bytePos );
 

bytePos = writeString( "IEND", bytePos );
 

crc.reset();
 

crc.update("IEND".getBytes());
 

crcValue = crc.getValue();
 

bytePos = writeInt4( (int) crcValue, bytePos );
 

}
 

}
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章