📄 writing image files.htm
字号:
3,3,3,3,3,3,3,3
};
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TD rowspan="12" colspan="1"><PRE> // Really rotten quality Q Table
private static int[] qtable4 = {
200,200,200,200,200,200,200,200,
200,200,200,200,200,200,200,200,
200,200,200,200,200,200,200,200,
200,200,200,200,200,200,200,200,
200,200,200,200,200,200,200,200,
200,200,200,200,200,200,200,200,
200,200,200,200,200,200,200,200,
200,200,200,200,200,200,200,200
};
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TD
rowspan="5" colspan="1"><PRE> public static void main(String args[]) {
JPEGWriterTest jtest = new JPEGWriterTest(args);
}
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TD rowspan="10" colspan="1"><PRE> // Load the source image.
private PlanarImage loadImage(String imageName) {
ParameterBlock pb = (new
ParameterBlock()).add(imageName);
PlanarImage src = JAI.create("fileload", pb);
if (src == null) {
System.out.println("Error in loading image " + imageName);
System.exit(1);
}
return src;
}
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TD rowspan="11" colspan="1"><PRE> // Create the image encoder.
private void encodeImage(PlanarImage img, FileOutputStream out)
{
encoder = ImageCodec.createImageEncoder("JPEG", out,
encodeParam);
try {
encoder.encode(img);
out.close();
} catch (IOException e) {
System.out.println("IOException at encoding..");
System.exit(1);
}
}
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TD rowspan="9" colspan="1"><PRE> private FileOutputStream createOutputStream(String outFile) {
FileOutputStream out = null;
try {
out = new FileOutputStream(outFile);
} catch(IOException e) {
System.out.println("IOException.");
System.exit(1);
}
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TD rowspan="3" colspan="1"><PRE> return out;
}
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TD rowspan="4"
colspan="1"><PRE> public JPEGWriterTest(String args[]) {
// Set parameters from command line arguments.
String inFile = "images/Parrots.tif";
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TD
rowspan="4" colspan="1"><PRE> FileOutputStream out1 = createOutputStream("out1.jpg");
FileOutputStream out2 = createOutputStream("out2.jpg");
FileOutputStream out3 = createOutputStream("out3.jpg");
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TD
rowspan="3" colspan="1"><PRE> // Create the source op image.
PlanarImage src = loadImage(inFile);
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TD><PRE> double[] constants = new double[3];
constants[0] = 0.0;
constants[1] = 0.0;
constants[2] = 0.0;
ParameterBlock pb = new ParameterBlock();
pb.addSource(src);
pb.add(constants);
</PRE><TR valign="top"><TD><PRE> // Create a new src image with weird tile sizes
ImageLayout layout = new ImageLayout();
layout.setTileWidth(57);
layout.setTileHeight(57);
RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT,
layout);
PlanarImage src1 = JAI.create("addconst", pb, hints);
</PRE><TR valign="top"><TD rowspan="2" colspan="1"><PRE> // ----- End src loading ------
</PRE><TR valign="top"><TR valign="top"><TD rowspan="5" colspan="1"><PRE> // Set the encoding parameters if necessary.
encodeParam = new JPEGEncodeParam();
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TD rowspan="2" colspan="1"><PRE> encodeParam.setQuality(0.1F);
</PRE><TR valign="top"><TR valign="top"><TD rowspan="4" colspan="1"><PRE> encodeParam.setHorizontalSubsampling(0, 1);
encodeParam.setHorizontalSubsampling(1, 2);
encodeParam.setHorizontalSubsampling(2, 2);
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TD
rowspan="4" colspan="1"><PRE> encodeParam.setVerticalSubsampling(0, 1);
encodeParam.setVerticalSubsampling(1, 1);
encodeParam.setVerticalSubsampling(2, 1);
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TD
rowspan="5" colspan="1"><PRE> encodeParam.setRestartInterval(64);
//encodeParam.setWriteImageOnly(false);
//encodeParam.setWriteTablesOnly(true);
//encodeParam.setWriteJFIFHeader(true);
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TD rowspan="4" colspan="1"><PRE> // Create the encoder.
encodeImage(src, out1);
PlanarImage dst1 = loadImage("out1.jpg");
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TD
rowspan="2" colspan="1"><PRE> // ----- End first encode ---------
</PRE><TR valign="top"><TR valign="top"><TD rowspan="3" colspan="1"><PRE> encodeParam.setLumaQTable(qtable1);
encodeParam.setChromaQTable(qtable2);
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TD rowspan="3"
colspan="1"><PRE> encodeImage(src, out2);
PlanarImage dst2 = loadImage("out2.jpg");
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TD rowspan="2"
colspan="1"><PRE> // ----- End second encode ---------
</PRE><TR valign="top"><TR valign="top"><TD rowspan="11" colspan="1"><PRE> encodeParam = new JPEGEncodeParam();
encodeImage(loadImage("images/BlackCat.tif"), out3);
PlanarImage dst3 = loadImage("out3.jpg");
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TD rowspan="2" colspan="1"><PRE> // ----- End third encode ---------
</PRE><TR valign="top"><TR valign="top"><TD rowspan="15" colspan="1"><PRE> setTitle ("JPEGWriter Test");
setLayout(new GridLayout(2, 2));
ScrollingImagePanel panel1 = new ScrollingImagePanel(src, 512,
400);
ScrollingImagePanel panel2 = new ScrollingImagePanel(dst1, 512,
400);
ScrollingImagePanel panel3 = new ScrollingImagePanel(dst2, 512,
400);
ScrollingImagePanel panel4 = new ScrollingImagePanel(dst3, 512,
400);
add(panel1);
add(panel2);
add(panel3);
add(panel4);
pack();
show(); }
}
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
valign="top"><TR valign="top">
<HR>
<P><A name=51712>
<H2>13.6 <IMG src="Writing Image Files.files/space.gif">Writing PNG Image
Files</H2></A>The Portable Network Graphics (PNG) format is a file standard
for compressed lossless bitmapped image files. A PNG file consists of an
eight-byte PNG <EM>signature</EM> followed by several <EM>chunks</EM>. The
signature identifies the file as a PNG file. The chunks provide additional
information about the image. The JAI codec architecture supports PNG 1.1 and
provides control over several of the chunks as described in this section.
<P><A name=51714>
<H3>13.6.1 <IMG src="Writing Image Files.files/space.gif">PNG Image
Layout</H3></A>PNG images can be encoded in one of three pixel types, as
defined by the subclass of <CODE>PNGEncodeParam</CODE>, as follows:
<P>
<TABLE cellPadding=3 border=3>
<CAPTION><FONT size=-1><B></B></FONT></CAPTION>
<TBODY>
<TR vAlign=top>
<TH><A name=51717>Pixel Type </A>
<TH><A name=51719>Description </A>
<TR vAlign=top>
<TD><A name=51721>PNGEncodeParam.Palette</A><BR>
<TD><A name=51723>Also known as <EM>indexed-color</EM>, where each pixel
is represented by a single sample that is an index into a supplied color
palette. The com.sun.media.jai.codec.PNGEncodeParam.Palette class
supports the encoding of palette pixel images.</A><BR>
<TR vAlign=top>
<TD><A name=51725>PNGEncodeParam.Gray</A><BR>
<TD><A name=51727>Each pixel is represented by a single sample that is a
grayscale level. The com.sun.media.jai.codec.PNGEncodeParam.Gray class
supports the encoding of grayscale pixel images.</A><BR>
<TR vAlign=top>
<TD><A name=51729>PNGEncodeParam.RGB</A><BR>
<TD><A name=51731>Also known as <EM>truecolor</EM>, where each pixel is
represented by three samples: red, green, and blue. The
com.sun.media.jai.codec.PNGEncodeParam.RGB class supports the encoding
of RGB pixel images.</A><BR></TR></TBODY></TABLE>
<P>Optionally, grayscale and RGB pixels can also include an alpha sample (see
<A
href="http://java.sun.com/products/java-media/jai/forDevelopers/jai1_0_1guide-unc/Encode.doc.html#53950">Section
13.6.6.12, "Transparency (tRNS Chunk)</A>").
<P>A call to the <CODE>getDefaultEncodeParam</CODE> method returns an instance
of:
<P>
<UL>
<LI><CODE>PNGEncodeParam.Palette</CODE> for an image with an
<CODE>IndexColorModel</CODE>.
<P></P></LI></UL>
<UL>
<LI><CODE>PNGEncodeParam.Gray</CODE> for an image with only one or two
bands.
<P></P></LI></UL>
<UL>
<LI><CODE>PNGEncodeParam.RGB</CODE> for all other images.
<P></P></LI></UL>This method provides no guarantee that the image can be
successfully encoded by the PNG encoder, since the encoder only performs a
superficial analysis of the image structure.
<P>
<TABLE border=0>
<TBODY>
<TR>
<TD><IMG src="Writing Image Files.files/cistine.gif"></TD>
<TD>
<HR>
<B>API:</B> <CODE>com.sun.media.jai.codec.PNGEncodeParam </CODE>
<HR>
</TD></TR></TBODY></TABLE><PRE><UL>
<LI>static PNGEncodeParam getDefaultEncodeParam(RenderedImage im)
<P></P></LI></UL></PRE>
<DL><A name=53271>
<DT>
<DD>returns an instance of <CODE>PNGEncodeParam.Palette</CODE>,
<CODE>PNGEncodeParam.Gray</CODE>, or <CODE>PNGEncodeParam.RGB</CODE>
appropriate for encoding the given image. </A>
<P></P></DD></DL><A name=53157>
<H3>13.6.2 <IMG src="Writing Image Files.files/space.gif">PNG
Filtering</H3></A>The PNG file definition allows the image data to be filtered
before it is compressed, which can improve the compressibility of the data.
PNG encoding supports five filtering algorithms, including "none," which
indicates no filtering. The filtering algorithms are described below.
<P>
<TABLE cellPadding=3 border=3>
<CAPTION><FONT size=-1><B><A name=53164><I>Table 13-3 </I><IMG
src="Writing Image Files.files/sm-blank.gif" border=0> PNG Filtering
Algorithms </A></B></FONT></CAPTION>
<TBODY>
<TR vAlign=top>
<TH><A name=53168>Parameter </A>
<TH><A name=53170>Description </A>
<TR vAlign=top>
<TD><A name=53172>PNG_FILTER_NONE</A><BR>
<TD><A name=53174>No filtering - the scanline is transmitted
unaltered.</A><BR>
<TR vAlign=top>
<TD><A name=53176>PNG_FILTER_SUB</A><BR>
<TD><A name=53178>The filter transmits the difference between each byte
and the value of the corresponding byte of the prior pixel.</A><BR>
<TR vAlign=top>
<TD><A name=53180>PNG_FILTER_UP</A><BR>
<TD><A name=53182>Similar to the Sub filter, except that the pixel
immediately above the current pixel, rather than just to its left, is
used as the predictor.</A><BR>
<TR vAlign=top>
<TD><A name=53184>PNG_FILTER_AVERAGE</A><BR>
<TD><A name=53186>The filter uses the average of the two neighboring
pixels (left and above) to predict the value of a pixel.</A><BR>
<TR vAlign=top>
<TD><A name=53188>PNG_FILTER_PAETH</A><BR>
<TD><A name=53190>The filter computes a simple linear function of the
three neighboring pixels (left, above, upper left), then chooses as
predictor the neighboring pixel closest to the computed
value.</A><BR></TR></TBODY></TABLE>
<P>The filtering can be different for each row of an image by using the
<CODE>filterRow</CODE> method. The method can be overridden to provide a
custom algorithm for choosing the filter type for a given row.
<P>The <CODE>filterRow</CODE> method is supplied with the current and previous
rows of the image. For the first row of the image, or of an interlacing pass,
the previous row array will be filled with zeros as required by the PNG
specification.
<P>The method is also supplied with five scratch arrays. These arrays may be
used within the method for any purpose. At method exit, the array at the index
given by the return value of the method should contain the filtered data. The
return value will also be used as the filter type.
<P>The default implementation of the method performs a trial encoding with
each of the filter types, and computes the sum of absolute values of the
differences between the raw bytes of the current row and the predicted values.
The index of the filter producing the smallest result is returned.
<P>As an example, to perform only "sub" filtering, this method could be
implemented (non-optimally) as follows:
<P><CAPTION><FONT size=-1><B></B></FONT></CAPTION>
<HR>
<TR valign="top"><TD rowspan="7" colspan="1"><PRE> for (int i = bytesPerPixel; i < bytesPerRow + bytesPerPixel; i++)
{
int curr = currRow[i] & 0xff;
int left = currRow[i - bytesPerPixel] & 0xff;
scratchRow[PNG_FILTER_SUB][i] = (byte)(curr - left);
}
return PNG_FILTER_SUB;
</PRE><TR valign="top"><TR valign="top"><TR valign="top"><TR valign="top"><TR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -