/*
* Copyright ( c ) 2016 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation .
*
* This code 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 General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
/*
* @ test
* @ bug 6334602
* @ summary Test verifies that when we create GIF image from Opaque PNG images
* it should not be transparent .
* @ modules java . desktop / com . sun . imageio . plugins . gif
* @ run main / manual OpaquePNGToGIFTest
*/
import java.awt.image.BufferedImage;
import com.sun.imageio.plugins.gif.GIFImageMetadata;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageTypeSpecifier;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public final class OpaquePNGToGIFTest extends Frame {
Image img = null ;
private Dimension prefImgSize = new Dimension(100 , 100 );
private Color canvasColor = new Color(0 , 255 , 0 );
File outputFile = null ;
ImageCanvas imageCanvas = new ImageCanvas();
FileOutputStream fos;
private static GridBagLayout layout;
private static JPanel mainControlPanel;
private static JPanel resultButtonPanel;
private static JPanel canvasPanel;
private static JLabel instructionText;
private static JButton startTestButton;
private static JButton passButton;
private static JButton failButton;
private static JDialog dialog;
private static Frame instructionFrame;
private static Frame imageFrame;
Toolkit tk;
ImageWriter writer = null ;
boolean testPassed, testGeneratedInterrupt, startButtonClicked;
private static Thread mainThread;
public OpaquePNGToGIFTest() throws Exception {
SwingUtilities.invokeAndWait(() -> {
try {
startTest();
} catch (Exception ex) {
Logger.getLogger(OpaquePNGToGIFTest.class .getName()).
log(Level.SEVERE, null , ex);
}
});
mainThread = Thread .currentThread();
try {
Thread .sleep(60000 );
} catch (InterruptedException e) {
if (!testPassed && testGeneratedInterrupt) {
throw new RuntimeException("Test failed or didnt run"
+ " properly" );
}
}
if (!testGeneratedInterrupt) {
if (img != null ) {
img.flush();
}
instructionFrame.dispose();
if (startButtonClicked) {
imageFrame.dispose();
}
fos.close();
Files.delete (outputFile.toPath());
throw new RuntimeException("user has not executed the test" );
}
}
public void startTest() throws Exception {
instructionFrame = new Frame();
dialog = new JDialog(instructionFrame);
dialog.setTitle("Instruction Dialog" );
layout = new GridBagLayout();
mainControlPanel = new JPanel(layout);
resultButtonPanel = new JPanel(layout);
canvasPanel = new JPanel();
GridBagConstraints gbc = new GridBagConstraints();
String instructions
= "<html> INSTRUCTIONS:<br><br>"
+ "After clicking on Start Test button you will see Red<br> "
+ " circle drawn with light blue background, if the circle<br>"
+ " color changes from Red to Green then press button Fail,<br>"
+ " if it stays Red then press button Pass.<br><br></html>" ;
instructionText = new JLabel();
instructionText.setText(instructions);
gbc.gridx = 0 ;
gbc.gridy = 0 ;
gbc.fill = GridBagConstraints.HORIZONTAL;
mainControlPanel.add(instructionText, gbc);
startTestButton = new JButton("Start Test" );
startTestButton.setActionCommand("Start Test" );
startTestButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
startButtonClicked = true ;
imageFrame = new Frame();
Iterator it = ImageIO.getImageWritersByFormatName("GIF" );
while (it.hasNext()) {
writer = (ImageWriter) it.next();
break ;
}
// read input opaque PNG image.
String fileName = "opaque_input.png" ;
String sep = System.getProperty("file.separator" );
String dir = System.getProperty("test.src" , "." );
System.out.println(dir + " " + sep);
String filePath = dir + sep + fileName;
File inputFile = new File(filePath);
ImageInputStream iis = ImageIO.
createImageInputStream(inputFile);
ImageReader reader = null ;
Iterator readerIter = ImageIO.getImageReaders(iis);
while (readerIter.hasNext()) {
reader = (ImageReader) readerIter.next();
break ;
}
reader.setInput(iis);
IIOMetadata imgData = reader.getImageMetadata(0 );
BufferedImage bi = reader.read(0 );
//create temporary GIF imageas output
File directory = new File(dir + sep);
outputFile = File.createTempFile("output" ,
".gif" , directory);
createAnimatedImage(bi, imgData,
writer, outputFile);
writer.dispose();
iis.close();
if (outputFile == null ) {
throw new RuntimeException("Unable to create output GIF"
+ " file" );
}
// extract GIF image using Toolkit and show it on a Panel.
tk = Toolkit.getDefaultToolkit();
img = tk.getImage(dir + sep + outputFile.getName());
directory.delete ();
imageCanvas.setBackground(canvasColor);
imageCanvas.setImage(img);
imageCanvas.setPreferredSize(prefImgSize);
canvasPanel.doLayout();
canvasPanel.add(imageCanvas);
imageFrame.add("Center" , canvasPanel);
imageFrame.setSize(200 , 200 );
imageFrame.setVisible(true );
imageFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
img.flush();
instructionFrame.dispose();
imageFrame.dispose();
fail();
} finally {
try {
fos.close();
Files.delete (outputFile.toPath());
} catch (IOException ex) {
Logger.getLogger(OpaquePNGToGIFTest.class .
getName()).log(Level.SEVERE, null ,
ex);
}
}
}
});
} catch (IOException ex) {
Logger.getLogger(OpaquePNGToGIFTest.class .getName()).
log(Level.SEVERE, null , ex);
}
}
});
passButton = new JButton("Pass" );
passButton.setActionCommand("Pass" );
passButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
if (img != null ) {
img.flush();
}
instructionFrame.dispose();
if (!startButtonClicked) {
fail();
} else {
imageFrame.dispose();
pass();
}
} finally {
try {
fos.close();
Files.delete (outputFile.toPath());
} catch (IOException ex) {
Logger.getLogger(OpaquePNGToGIFTest.class .
getName()).log(Level.SEVERE, null , ex);
}
}
}
});
failButton = new JButton("Fail" );
failButton.setActionCommand("Fail" );
failButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
if (img != null ) {
img.flush();
}
instructionFrame.dispose();
if (!startButtonClicked) {
fail();
} else {
imageFrame.dispose();
fail();
}
} finally {
try {
fos.close();
Files.delete (outputFile.toPath());
} catch (IOException ex) {
Logger.getLogger(OpaquePNGToGIFTest.class .
getName()).log(Level.SEVERE, null , ex);
}
}
}
});
gbc.gridx = 1 ;
gbc.gridy = 0 ;
resultButtonPanel.add(startTestButton, gbc);
gbc.gridx = 2 ;
gbc.gridy = 0 ;
resultButtonPanel.add(passButton, gbc);
gbc.gridx = 3 ;
gbc.gridy = 0 ;
resultButtonPanel.add(failButton, gbc);
gbc.gridx = 0 ;
gbc.gridy = 1 ;
mainControlPanel.add(resultButtonPanel, gbc);
dialog.add(mainControlPanel);
dialog.setSize(400 , 200 );
dialog.setLocationRelativeTo(null );
dialog.setVisible(true );
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
try {
if (img != null ) {
img.flush();
}
instructionFrame.dispose();
if (!startButtonClicked) {
fail();
} else {
imageFrame.dispose();
fail();
}
} finally {
try {
fos.close();
Files.delete (outputFile.toPath());
} catch (IOException ex) {
Logger.getLogger(OpaquePNGToGIFTest.class .
getName()).log(Level.SEVERE, null , ex);
}
}
}
});
}
public synchronized void pass() {
testPassed = true ;
testGeneratedInterrupt = true ;
mainThread.interrupt();
}
public synchronized void fail() {
testPassed = false ;
testGeneratedInterrupt = true ;
mainThread.interrupt();
}
public void createAnimatedImage(BufferedImage bi, IIOMetadata metadata,
ImageWriter writer, File outputFile) {
try {
fos = new FileOutputStream(outputFile);
ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
System.out.println(ios);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
IIOMetadata streamData = writer.getDefaultStreamMetadata(param);
writer.prepareWriteSequence(streamData);
ImageTypeSpecifier specify = new ImageTypeSpecifier(bi);
IIOMetadata imgData = writer.convertImageMetadata(
(IIOMetadata) metadata, specify, param);
GIFImageMetadata gifData = setAnimationProperties(imgData);
IIOImage iim = new IIOImage(bi, null , gifData);
param.setProgressiveMode(param.MODE_DISABLED);
writer.writeToSequence(iim, param);
writer.endWriteSequence();
ios.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public GIFImageMetadata setAnimationProperties(IIOMetadata data) {
ArrayList appIDs = new ArrayList();
appIDs.add(new String("NETSCAPE" ).getBytes());
ArrayList authCodes = new ArrayList();
authCodes.add(new String("2.0" ).getBytes());
ArrayList appData = new ArrayList();
byte [] authData = {1 , 0 , 0 };
appData.add(authData);
GIFImageMetadata gifData = (GIFImageMetadata) data;
gifData.delayTime = 200 ;
// If we set disposalMethod to 2 then only the issue is reproduced.
gifData.disposalMethod = 2 ;
gifData.userInputFlag = false ;
gifData.applicationIDs = appIDs;
gifData.authenticationCodes = authCodes;
gifData.applicationData = appData;
return gifData;
}
public static void main(String args[]) throws Exception {
OpaquePNGToGIFTest test = new OpaquePNGToGIFTest();
}
class ImageCanvas extends Canvas {
Image im = null ;
public void setImage(Image img) {
im = img;
}
public void clearImage() {
im = null ;
repaint();
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
if (im != null ) {
g2d.drawImage(im, 1 , 1 , getWidth(), getHeight(), this );
}
}
}
}
Messung V0.5 in Prozent C=94 H=93 G=93
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland