savepicture.java
来自「一个简单的visio程序。」· Java 代码 · 共 425 行
JAVA
425 行
/**
* @(#)SavePicture.java 98/06/18
*
* Copyright 1997-1998 by Halcyon Software Inc.,
* All rights reserved.
*
* SavePicture is a class which takes a Picture and saves it to a stream
* using the GIF file format.
*
* @version IB4J1.3
*/
package HPCore.stdstmt;
import java.io.*;
import java.awt.*;
import java.net.*;
import java.awt.image.*;
import HECore.stddata.*;
import HPCore.Exception.*;
import HAB.object.*;
public class SavePicture {
private final int RES_CODES = 2;
private final short HASH_FREE = (short)0xFFFF;
private final short NEXT_FIRST = (short)0xFFFF;
private final int MAXBITS = 12;
private final int MAXSTR = (1 << MAXBITS);
private final short HASHSIZE = 9973;
private final short HASHSTEP = 2039;
private byte byte_;
private byte separator_;
private byte backgroundColorIndex_, pixelAspectRatio_;
private short leftPosition_, topPosition_;
byte[] strChr_ = new byte[MAXSTR];
short[] strNxt_ = new short[MAXSTR];
short[] strHsh_ = new short[HASHSIZE];
short numStrings_;
short width_, height_;
int numColors_;
byte[] buffer_ = new byte[256];
int index_ = 0, bitsLeft_ = 8;
byte pixels_[], colors_[];
public void SavePicture(Picture urlpicture, Variant filename) throws java.lang.Exception
{
//String up_ = urlpicture.strValue();
String fn_;
int type = filename.getType();
switch (type){
case Variant.V_NULL:
throw new HpException(94, "Invalid use of null");
case Variant.V_DATE: // Hope
if(filename.strValue() == null)
throw new HpException(75, "Path or File access error");
else {
if(filename.strValue().indexOf('/') == -1 ||
filename.strValue().indexOf('\\')== -1)
{fn_ = filename.strValue(); break;}
else throw new HpException(76, "Path not found");
}
case Variant.V_BOL:
case Variant.V_DBL:
case Variant.V_LONG:
case Variant.V_CURR:
case Variant.V_SINGLE:
case Variant.V_INT:
case Variant.V_BYTE:
// case Variant.V_ERR: // Hope
case Variant.V_STR:
case Variant.V_FIX_STR:
fn_ = filename.strValue();
break;
default: throw new HpException(53, "File not found");
}
if (fn_ == null)
throw new HpException(53, "File not found");
//Frame f = new Frame("TZGIF");
//Image image = null;//((Picture)urlpicture.getObject().getobj()).image;
Image image = urlpicture.image;
//Image image = f.getToolkit().getImage(new URL(up_));
if (image == null)
throw new HpException(481, "Invalid picture");
/*
MediaTracker tracker = new MediaTracker(f);
tracker.addImage(image, 0);
try {
tracker.waitForID(0);
} catch (InterruptedException e) { ; }
if (tracker.statusID(0, true) != MediaTracker.COMPLETE)
throw new HpException(99, "Could not save," +
" Use statusID() to check for error is " +
tracker.statusID(0, true));
*/
GIFEncoder(image);
OutputStream output = new BufferedOutputStream(
new FileOutputStream(fn_));
SavePicture(output);
//System.exit(0);
return;
}
void SavePicture(OutputStream output) throws IOException
{
WriteString(output, "GIF87a"); //GIF89a
WriteWord(output, width_);
WriteWord(output, height_);
SetGlobalColorTableSize((byte)(BitsNeeded(numColors_) - 1));
SetGlobalColorTableFlag((byte)1);
SetSortFlag((byte)0);
SetColorResolution((byte)7);
backgroundColorIndex_ = 0;
pixelAspectRatio_ = 0;
output.write(byte_);
output.write(backgroundColorIndex_);
output.write(pixelAspectRatio_);
output.write(colors_, 0, colors_.length);
separator_ = (byte)',';
leftPosition_ = 0;
topPosition_ = 0;
byte_ = 0;
SetLocalColorTableSize((byte)0);
SetReserved((byte)0);
SetShortFlag((byte)0);
SetInterlaceFlag((byte)0);
SetLocalColorTableFlag((byte)0);
output.write(separator_);
WriteWord(output, leftPosition_);
WriteWord(output, topPosition_);
WriteWord(output, width_);
WriteWord(output, height_);
output.write(byte_);
byte codesize = BitsNeeded(numColors_);
if (codesize == 1)
++codesize;
output.write(codesize); //size
LZWCompress(output, codesize, pixels_); //load image
output.write(0); //no very vaild
separator_ = (byte)';';
output.write(separator_);
WriteWord(output, leftPosition_);
WriteWord(output, topPosition_);
WriteWord(output, (byte)0);
WriteWord(output, (byte)0);
output.write(byte_);
output.flush(); //flush
}
void GIFEncoder(Image image) throws HpException
{
width_ = (short)image.getWidth(null);
height_ = (short)image.getHeight(null);
int values[] = new int[width_ * height_];
PixelGrabber grabber = new PixelGrabber(
image, 0, 0, width_, height_, values, 0, width_);
try {
if(grabber.grabPixels() != true)
throw new HpException(111, "Grabber returned false: " +
grabber.status());
} catch (InterruptedException e) { ; }
byte r[][] = new byte[width_][height_];
byte g[][] = new byte[width_][height_];
byte b[][] = new byte[width_][height_];
int index = 0;
for (int y = 0; y < height_; ++y)
for (int x = 0; x < width_; ++x) {
r[x][y] = (byte)((values[index] >> 16) & 0xFF);
g[x][y] = (byte)((values[index] >> 8) & 0xFF);
b[x][y] = (byte)((values[index]) & 0xFF);
++index;
}
ToIndexedColor(r, g, b);
}
void ToIndexedColor(byte r[][], byte g[][], byte b[][]) throws HpException
{
pixels_ = new byte[width_ * height_];
colors_ = new byte[256 * 3];
int colornum = 0;
for (int x = 0; x < width_; ++x) {
for (int y = 0; y < height_; ++y) {
int search;
for (search = 0; search < colornum; ++search)
if (colors_[search * 3] == r[x][y] &&
colors_[search * 3 + 1] == g[x][y] &&
colors_[search * 3 + 2] == b[x][y])
break;
if (search > 255)
throw new HpException(103, "Too many colors.");
pixels_[y * width_ + x] = (byte)search;
if (search == colornum) {
colors_[search * 3] = r[x][y];
colors_[search * 3 + 1] = g[x][y];
colors_[search * 3 + 2] = b[x][y];
++colornum;
}
}
}
numColors_ = 1 << BitsNeeded(colornum);
byte copy[] = new byte[numColors_ * 3];
System.arraycopy(colors_, 0, copy, 0, numColors_ * 3);
colors_ = copy;
}
void LZWCompress(OutputStream output, int codesize,
byte toCompress[]) throws IOException {
byte c;
short index;
int clearcode, endofinfo, numbits, limit, errcode;
short prefix = (short)0xFFFF;
clearcode = 1 << codesize;
endofinfo = clearcode + 1;
numbits = codesize + 1;
limit = (1 << numbits) - 1;
ClearTable(codesize);
WriteBits(output, clearcode, numbits);
for (int loop = 0; loop < toCompress.length; ++loop) {
c = toCompress[loop];
if ((index = FindCharString(prefix, c)) != -1)
prefix = index;
else {
WriteBits(output, prefix, numbits);
if (AddCharString(prefix, c) > limit) {
if (++numbits > 12) {
WriteBits(output, clearcode, numbits - 1);
ClearTable(codesize);
numbits = codesize + 1;
}
limit = (1 << numbits) - 1;
}
prefix = (short)((short)c & 0xFF);
}
}
if (prefix != -1)
WriteBits(output, prefix, numbits);
WriteBits(output, endofinfo, numbits);
Flush(output);
}
private void Flush(OutputStream output_) throws IOException {
int numBytes = index_ + (bitsLeft_ == 8 ? 0 : 1);
if (numBytes > 0) {
output_.write(numBytes);
output_.write(buffer_, 0, numBytes);
buffer_[0] = 0;
index_ = 0;
bitsLeft_ = 8;
}
}
private void WriteBits(OutputStream output_, int bits, int numbits) throws IOException {
int bitsWritten = 0;
int numBytes = 255;
do {
if ((index_ == 254 && bitsLeft_ == 0) || index_ > 254) {
output_.write(numBytes);
output_.write(buffer_, 0, numBytes);
buffer_[0] = 0;
index_ = 0;
bitsLeft_ = 8;
}
if (numbits <= bitsLeft_) {
buffer_[index_] |= (bits & ((1 << numbits) - 1)) <<
(8 - bitsLeft_);
bitsWritten += numbits;
bitsLeft_ -= numbits;
numbits = 0;
}
else {
buffer_[index_] |= (bits & ((1 << bitsLeft_) - 1)) <<
(8 - bitsLeft_);
bitsWritten += bitsLeft_;
bits >>= bitsLeft_;
numbits -= bitsLeft_;
buffer_[++index_] = 0;
bitsLeft_ = 8;
}
} while (numbits != 0);
}
private int AddCharString(short index, byte b) {
int hshidx;
if (numStrings_ >= MAXSTR)
return 0xFFFF;
hshidx = Hash(index, b);
while (strHsh_[hshidx] != HASH_FREE)
hshidx = (hshidx + HASHSTEP) % HASHSIZE;
strHsh_[hshidx] = numStrings_;
strChr_[numStrings_] = b;
strNxt_[numStrings_] = (index != HASH_FREE) ? index : NEXT_FIRST;
return numStrings_++;
}
private short FindCharString(short index, byte b) {
int hshidx, nxtidx;
if (index == HASH_FREE)
return b;
hshidx = Hash(index, b);
while ((nxtidx = strHsh_[hshidx]) != HASH_FREE) {
if (strNxt_[nxtidx] == index && strChr_[nxtidx] == b)
return (short)nxtidx;
hshidx = (hshidx + HASHSTEP) % HASHSIZE;
}
return (short)0xFFFF;
}
private void ClearTable(int codesize) {
numStrings_ = 0;
for (int q = 0; q < HASHSIZE; q++) {
strHsh_[q] = HASH_FREE;
}
int w = (1 << codesize) + RES_CODES;
for (int q = 0; q < w; q++)
AddCharString((short)0xFFFF, (byte)q);
}
private int Hash(short index, byte lastbyte) {
return ((int)((short)(lastbyte << 8) ^ index) & 0xFFFF) % HASHSIZE;
}
private byte BitsNeeded(int n) {
byte ret = 1;
if (n-- == 0)
return 0;
while ((n >>= 1) != 0)
++ret;
return ret;
}
private void WriteWord(OutputStream output,
short w) throws IOException {
output.write(w & 0xFF);
output.write((w >> 8) & 0xFF);
}
void WriteString(OutputStream output,
String string) throws IOException {
for (int loop = 0; loop < string.length(); ++loop)
output.write((byte)(string.charAt(loop)));
}
private void SetGlobalColorTableSize(byte num) {
byte_ |= (num & 7);
}
private void SetSortFlag(byte num) {
byte_ |= (num & 1) << 3;
}
private void SetColorResolution(byte num) {
byte_ |= (num & 7) << 4;
}
private void SetGlobalColorTableFlag(byte num) {
byte_ |= (num & 1) << 7;
}
//ImageDescriptor
private void SetLocalColorTableSize(byte num) {
byte_ |= (num & 7);
}
private void SetReserved(byte num) {
byte_ |= (num & 3) << 3;
}
private void SetShortFlag(byte num) {
byte_ |= (num & 1) << 5;
}
private void SetInterlaceFlag(byte num) {
byte_ |= (num & 1) << 6;
}
private void SetLocalColorTableFlag(byte num) {
byte_ |= (num & 1) << 7;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?