|
Navigate!
Articles
Essential JPEG
IPN Wizard
Wide-Angle Photo Corrector
The Eye Mouse
Inverted Pendulum Project
Digital
Goods Delivery Verification System
| |
Bug #2 submitted by Jerry Huxtable
On images whose dimensions are not mutliples of 8, a "dirty" edge results in
the compressed image.
Jerry also confirmed Bug #1.
Bug #1 submitted by Nick Didkovsky
Tested the range of qualities 0..20, and in that range, only saving with qualities of
3, 5, 9, 16, 17, and 18 result in JPEG images that Adobe PhotoShop can import. Other
qualities result in file load errors: "Jpeg marker segment length too short"
Tested a few higher ones, too. 100 did not work, 98 and 99 did.
Netscape, on the other hand, loads all of them fine.
Source below...
I also tried your code (and my test program) on an SGI O2. The O2's native image
viewer also had complaints with the same images, so there's definitely something funny
with the length of some segment.
Best,
Nick, drnerve@ingress.com
/* Nick Didkovsky 4/10/98 12:44PM
JpegSaverTest.java
Draw some stuff onto an Image and save it as a JPEG.
*/
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class JpegSaverTest extends Frame implements WindowListener,
ActionListener, AdjustmentListener {
JpegSaverTest() {
setTitle("Test JPEG Saving");
myCanvas = new ImageCanvas();
myCanvas.setSize(320,200);
add("North", myCanvas);
Panel p = new Panel();
p.setLayout(new BorderLayout());
Panel t = new Panel();
t.setLayout(new BorderLayout());
qualityScrollbar = new Scrollbar(Scrollbar.HORIZONTAL, jpegQuality, 1,
0, 101);
t.add("North",qualityScrollbar);
qualityLabel = new Label("Quality: " + jpegQuality);
t.add("South", qualityLabel);
p.add("North", t);
saveButton = new Button("save");
p.add("Center", saveButton);
add("South", p);
addWindowListener(this);
saveButton.addActionListener(this);
qualityScrollbar.addAdjustmentListener(this);
System.out.println("Nick Didkovsky, drnerve@ingress.com");
}
// WindowListener
public void windowClosed(WindowEvent event) {
}
public void windowDeiconified(WindowEvent event) {
}
public void windowIconified(WindowEvent event) {
}
public void windowActivated(WindowEvent event) {
}
public void windowDeactivated(WindowEvent event) {
}
public void windowOpened(WindowEvent event) {
}
public void windowClosing(WindowEvent event) {
System.exit(0);
}
void saveJPEG() {
try {
if (myCanvas.getImage() != null) {
String name = "test" + jpegQuality + ".jpg";
System.out.println("saving JPEG file " + name + " with quality " +
jpegQuality);
FileOutputStream f = new FileOutputStream(name);
(new JpegEncoder(myCanvas.getImage(), jpegQuality, f)).Compress();
f.close();
System.out.println("done");
} else {
System.out.println("No image ready in canvas");
}
}
catch (Exception e) {
System.out.println("SAVE JPEG ERROR\n" + e);
}
}
void adjustQuality(int v) {
jpegQuality = v;
qualityLabel.setText("Quality: " + jpegQuality);
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == saveButton) saveJPEG();
}
public void adjustmentValueChanged(AdjustmentEvent event) {
Object source = event.getSource();
if (source == qualityScrollbar)
adjustQuality(qualityScrollbar.getValue());
}
public static void main(String args[]) {
JpegSaverTest g = new JpegSaverTest();
g.pack();
g.setVisible(true);
}
Button saveButton;
Scrollbar qualityScrollbar;
Label qualityLabel;
int jpegQuality = 75;
ImageCanvas myCanvas;
}
/** Just a place to do some drawing */
class ImageCanvas extends Canvas {
public Image getImage() {
return offscreenImage;
}
private void buildOffscreenImage() {
offscreenImage = createImage(imgWidth, imgHeight);
if (offscreenImage != null) {
System.out.println("Image buffer built");
} else {
System.out.println("Image buffer not built");
}
}
public void paint(Graphics g) {
Rectangle bounds = getBounds();
imgWidth = bounds.width;
imgHeight = bounds.height;
if (offscreenImage == null) buildOffscreenImage();
if (offscreenImage != null) {
Graphics offscreenGraphics = offscreenImage.getGraphics();
for (int i=0; i<imgWidth; i++) {
offscreenGraphics.setColor(new Color(i % 255, Math.abs((255 - i) %
255), 100));
offscreenGraphics.drawLine(i,i,imgWidth-i,i);
}
g.drawImage(offscreenImage, 0, 0, this);
offscreenGraphics.dispose();
}
}
private Image offscreenImage;
int imgWidth=640;
int imgHeight=400;
}
|