Initial commit of working code
This commit is contained in:
20
.classpath
Normal file
20
.classpath
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-13">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="src" output="target/classes" path="src">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="optional" value="true"/>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||||
|
<attributes>
|
||||||
|
<attribute name="maven.pomderived" value="true"/>
|
||||||
|
</attributes>
|
||||||
|
</classpathentry>
|
||||||
|
<classpathentry kind="output" path="target/classes"/>
|
||||||
|
</classpath>
|
||||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
bin/
|
||||||
|
target/
|
||||||
|
.DS_Store
|
||||||
23
.project
Normal file
23
.project
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>ImageWitch</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
||||||
15
.settings/org.eclipse.jdt.core.prefs
Normal file
15
.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=13
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=13
|
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||||
|
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||||
|
org.eclipse.jdt.core.compiler.release=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.source=13
|
||||||
4
.settings/org.eclipse.m2e.core.prefs
Normal file
4
.settings/org.eclipse.m2e.core.prefs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
activeProfiles=
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
resolveWorkspaceProjects=true
|
||||||
|
version=1
|
||||||
30
pom.xml
Normal file
30
pom.xml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>ImageWitch</groupId>
|
||||||
|
<artifactId>ImageWitch</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<build>
|
||||||
|
<sourceDirectory>src</sourceDirectory>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<release>13</release>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.drewnoakes</groupId>
|
||||||
|
<artifactId>metadata-extractor</artifactId>
|
||||||
|
<version>2.15.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.imgscalr</groupId>
|
||||||
|
<artifactId>imgscalr-lib</artifactId>
|
||||||
|
<version>4.2</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
486
src/ImageWitchGui.java
Normal file
486
src/ImageWitchGui.java
Normal file
@@ -0,0 +1,486 @@
|
|||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.GridBagLayout;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.image.AffineTransformOp;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.ImageObserver;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.InputVerifier;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JProgressBar;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import javax.swing.event.DocumentListener;
|
||||||
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
|
||||||
|
import org.imgscalr.Scalr.Rotation;
|
||||||
|
|
||||||
|
import com.drew.imaging.ImageMetadataReader;
|
||||||
|
import com.drew.metadata.Metadata;
|
||||||
|
import com.drew.metadata.MetadataException;
|
||||||
|
import com.drew.metadata.exif.ExifIFD0Directory;
|
||||||
|
|
||||||
|
public class ImageWitchGui extends JFrame {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
public static final String[] supportedExtensions =
|
||||||
|
{"jpg","jpeg","png","gif"};
|
||||||
|
|
||||||
|
File[] selectedFiles = null;
|
||||||
|
|
||||||
|
JTextField heightField;
|
||||||
|
JTextField widthField;
|
||||||
|
|
||||||
|
Integer maxWidth = 0;
|
||||||
|
Integer maxHeight = 0;
|
||||||
|
Boolean errorNotified = false;
|
||||||
|
|
||||||
|
JButton loadButton;
|
||||||
|
JButton resizeButton;
|
||||||
|
JProgressBar progressBar;
|
||||||
|
volatile boolean conversionRunning;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
//Schedule a job for the event-dispatching thread:
|
||||||
|
//creating and showing this application's GUI.
|
||||||
|
javax.swing.SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
ImageWitchGui gui = new ImageWitchGui();
|
||||||
|
gui.setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||||
|
gui.createAndShowGui();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageWitchGui() {
|
||||||
|
setTitle("ImageWitch");
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel(
|
||||||
|
UIManager.getCrossPlatformLookAndFeelClassName());
|
||||||
|
} catch (Exception e) {}
|
||||||
|
|
||||||
|
InputVerifier verifier = new NumberInputVerifier();
|
||||||
|
|
||||||
|
heightField = new JTextField("0");
|
||||||
|
heightField.setColumns(10);
|
||||||
|
heightField.setInputVerifier(verifier);
|
||||||
|
heightField.getDocument().addDocumentListener(
|
||||||
|
new FieldListener(heightField));
|
||||||
|
|
||||||
|
widthField = new JTextField("0");
|
||||||
|
widthField.setColumns(10);
|
||||||
|
widthField.setInputVerifier(verifier);
|
||||||
|
widthField.getDocument().addDocumentListener(
|
||||||
|
new FieldListener(widthField));
|
||||||
|
|
||||||
|
loadButton = new JButton("Load Files");
|
||||||
|
loadButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
JFileChooser chooser = new JFileChooser();
|
||||||
|
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
||||||
|
chooser.setMultiSelectionEnabled(true);
|
||||||
|
chooser.setFileFilter(
|
||||||
|
new FileNameExtensionFilter("Image Files",
|
||||||
|
supportedExtensions));
|
||||||
|
int returnVal = chooser.showOpenDialog(ImageWitchGui.this);
|
||||||
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
||||||
|
selectedFiles = chooser.getSelectedFiles();
|
||||||
|
resizeButton.setEnabled(true);
|
||||||
|
errorNotified = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
progressBar.setString("Ready");
|
||||||
|
progressBar.setValue(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
resizeButton = new JButton("Resize");
|
||||||
|
resizeButton.setEnabled(false);
|
||||||
|
resizeButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (conversionRunning) {
|
||||||
|
conversionRunning = false;
|
||||||
|
loadButton.setEnabled(true);
|
||||||
|
resizeButton.setText("Resize");
|
||||||
|
} else {
|
||||||
|
errorNotified = false;
|
||||||
|
loadButton.setEnabled(false);
|
||||||
|
conversionRunning = true;
|
||||||
|
resizeButton.setText("Cancel");
|
||||||
|
Thread conversionThread = new Thread() {
|
||||||
|
public void run() {
|
||||||
|
convertFiles(selectedFiles);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
conversionThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
progressBar = new JProgressBar();
|
||||||
|
progressBar.setIndeterminate(false);
|
||||||
|
progressBar.setStringPainted(true);
|
||||||
|
progressBar.setString("Ready");
|
||||||
|
progressBar.setValue(0);
|
||||||
|
progressBar.setMaximum(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void createAndShowGui() {
|
||||||
|
JLabel label;
|
||||||
|
JPanel panel = new JPanel(new GridBagLayout());
|
||||||
|
getContentPane().add(panel);
|
||||||
|
GridBagConstraints c = new GridBagConstraints();
|
||||||
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
|
||||||
|
label = new JLabel("Max Width: ");
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 0;
|
||||||
|
c.insets = new Insets(2, 2, 2, 2);
|
||||||
|
c.gridheight = 1;
|
||||||
|
c.gridwidth = 1;
|
||||||
|
c.weightx = 1.0;
|
||||||
|
c.weighty = 1.0;
|
||||||
|
panel.add(label, c);
|
||||||
|
|
||||||
|
c.gridx = 1;
|
||||||
|
c.gridy = 0;
|
||||||
|
panel.add(widthField, c);
|
||||||
|
|
||||||
|
label = new JLabel("Max Height: ");
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 1;
|
||||||
|
panel.add(label, c);
|
||||||
|
|
||||||
|
c.gridx = 1;
|
||||||
|
c.gridy = 1;
|
||||||
|
panel.add(heightField, c);
|
||||||
|
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 2;
|
||||||
|
panel.add(loadButton, c);
|
||||||
|
|
||||||
|
c.gridx = 1;
|
||||||
|
c.gridy = 2;
|
||||||
|
panel.add(resizeButton, c);
|
||||||
|
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 3;
|
||||||
|
c.gridwidth = 2;
|
||||||
|
c.insets = new Insets(0, 0, 0, 0);
|
||||||
|
c.fill = GridBagConstraints.BOTH;
|
||||||
|
panel.add(progressBar, c);
|
||||||
|
|
||||||
|
this.pack();
|
||||||
|
this.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getExtension(String filename) {
|
||||||
|
String extension;
|
||||||
|
|
||||||
|
extension = filename.substring(filename.lastIndexOf(".")+1).toLowerCase();
|
||||||
|
if (extension.equals("jpeg")) {
|
||||||
|
extension = "jpg";
|
||||||
|
}
|
||||||
|
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getNewFilename(String filename) {
|
||||||
|
String newFilename;
|
||||||
|
|
||||||
|
int dotIdx = filename.lastIndexOf(".");
|
||||||
|
newFilename = filename.substring(0, dotIdx) +
|
||||||
|
"_scaled." + getExtension(filename);
|
||||||
|
|
||||||
|
return newFilename;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dimension getNewDimensions(int maxWidth, int maxHeight,
|
||||||
|
BufferedImage image) {
|
||||||
|
Dimension dim = new Dimension();
|
||||||
|
double sourceRatio, targetRatio;
|
||||||
|
int targetWidth, targetHeight;
|
||||||
|
|
||||||
|
sourceRatio = (double) image.getWidth() / (double) image.getHeight();
|
||||||
|
targetRatio = (double) maxWidth / (double) maxHeight;
|
||||||
|
|
||||||
|
if (maxWidth < 0 && maxHeight < 0) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"At least one of width and height must be selected");
|
||||||
|
} else if (maxWidth <= 0 ||
|
||||||
|
(maxHeight > 0 && targetRatio > sourceRatio)) {
|
||||||
|
targetHeight = maxHeight;
|
||||||
|
targetWidth = (int) (targetHeight * sourceRatio);
|
||||||
|
|
||||||
|
} else if (maxHeight <= 0 ||
|
||||||
|
(maxWidth > 0 && targetRatio < sourceRatio)) {
|
||||||
|
targetWidth = maxWidth;
|
||||||
|
targetHeight = (int) (targetWidth / sourceRatio);
|
||||||
|
} else {
|
||||||
|
targetWidth = maxWidth;
|
||||||
|
targetHeight = maxHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
dim.height = targetHeight;
|
||||||
|
dim.width = targetWidth;
|
||||||
|
|
||||||
|
return dim;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedImage rotateUpright(BufferedImage image, File file) {
|
||||||
|
Metadata metadata;
|
||||||
|
ExifIFD0Directory exifIFD0;
|
||||||
|
int orientation;
|
||||||
|
AffineTransform transform;
|
||||||
|
BufferedImage uprightImage;
|
||||||
|
AffineTransformOp transformOp;
|
||||||
|
|
||||||
|
try {
|
||||||
|
metadata = ImageMetadataReader.readMetadata(file);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
exifIFD0 = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
orientation = exifIFD0.getInt(ExifIFD0Directory.TAG_ORIENTATION);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
transform = new AffineTransform();
|
||||||
|
|
||||||
|
switch (orientation) {
|
||||||
|
case 6: // [Exif IFD0] Orientation - Right side, top (Rotate 90 CW)
|
||||||
|
uprightImage = new BufferedImage(image.getHeight(), image.getWidth(), image.getType());
|
||||||
|
transform.translate(image.getHeight() / 2, image.getWidth() / 2);
|
||||||
|
transform.rotate(Math.PI/2);
|
||||||
|
transform.translate(-image.getWidth() / 2, -image.getHeight() / 2);
|
||||||
|
transformOp = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
|
||||||
|
transformOp.filter(image, uprightImage);
|
||||||
|
break;
|
||||||
|
case 3: // [Exif IFD0] Orientation - Bottom, right side (Rotate 180)
|
||||||
|
uprightImage = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||||
|
transform.translate(image.getHeight() / 2, image.getWidth() / 2);
|
||||||
|
transform.rotate(Math.PI);
|
||||||
|
transform.translate(-image.getHeight() / 2, -image.getWidth() / 2);
|
||||||
|
transformOp = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
|
||||||
|
transformOp.filter(image, uprightImage);
|
||||||
|
break;
|
||||||
|
case 8: // [Exif IFD0] Orientation - Left side, bottom (Rotate 270 CW)
|
||||||
|
uprightImage = new BufferedImage(image.getHeight(), image.getWidth(), image.getType());
|
||||||
|
transform.translate(image.getHeight() / 2, image.getWidth() / 2);
|
||||||
|
transform.rotate(-Math.PI/2);
|
||||||
|
transform.translate(-image.getWidth() / 2, -image.getHeight() / 2);
|
||||||
|
transformOp = new AffineTransformOp(transform, AffineTransformOp.TYPE_BILINEAR);
|
||||||
|
transformOp.filter(image, uprightImage);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
uprightImage = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
return uprightImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateProgress(int progress, int maxValue, String text) {
|
||||||
|
javax.swing.SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
System.out.println(text);
|
||||||
|
if (maxValue != progressBar.getMaximum()) {
|
||||||
|
progressBar.setMaximum(maxValue);
|
||||||
|
}
|
||||||
|
progressBar.setValue(progress);
|
||||||
|
progressBar.setString(text);
|
||||||
|
|
||||||
|
if (progress == maxValue) {
|
||||||
|
loadButton.setEnabled(true);
|
||||||
|
resizeButton.setText("Resize");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void convertFiles(File[] files) {
|
||||||
|
BufferedImage oldImage;
|
||||||
|
String newFilename;
|
||||||
|
int index = 0;
|
||||||
|
int numFiles = files.length;
|
||||||
|
|
||||||
|
progressBar.setMaximum(numFiles);
|
||||||
|
for (File oldFile : files) {
|
||||||
|
if (!conversionRunning) {
|
||||||
|
updateProgress(0, 1, "Cancelled");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
oldImage = ImageIO.read(oldFile);
|
||||||
|
newFilename = getNewFilename(oldFile.getAbsolutePath());
|
||||||
|
oldImage = rotateUpright(oldImage, oldFile);
|
||||||
|
resizeAndSaveImage(oldImage, maxWidth, maxHeight, newFilename);
|
||||||
|
|
||||||
|
progressBar.setValue(index);
|
||||||
|
index++;
|
||||||
|
updateProgress(index, numFiles,
|
||||||
|
"Processing " + Integer.toString(index) +
|
||||||
|
" of " + Integer.toString(numFiles));
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (!errorNotified) {
|
||||||
|
errorNotified = true;
|
||||||
|
JOptionPane.showMessageDialog(ImageWitchGui.this,
|
||||||
|
"<html>Unable to read file: <br>" +
|
||||||
|
oldFile.getAbsolutePath() +
|
||||||
|
"<br><br>Other files may be affected.",
|
||||||
|
"Read Error",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateProgress(numFiles, numFiles, "Done");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resizeAndSaveImage(BufferedImage image,
|
||||||
|
int maxWidth, int maxHeight,
|
||||||
|
String newFilename)
|
||||||
|
throws IllegalArgumentException
|
||||||
|
{
|
||||||
|
Image newImage;
|
||||||
|
BufferedImage renderedImage;
|
||||||
|
ImageSaver saver;
|
||||||
|
Dimension newDim;
|
||||||
|
|
||||||
|
newDim = getNewDimensions(maxWidth, maxHeight, image);
|
||||||
|
newImage = image.getScaledInstance(
|
||||||
|
newDim.width, newDim.height, Image.SCALE_SMOOTH);
|
||||||
|
renderedImage = new BufferedImage(
|
||||||
|
newDim.width, newDim.height, BufferedImage.TYPE_INT_RGB);
|
||||||
|
saver = new ImageSaver(newFilename, renderedImage);
|
||||||
|
renderedImage.getGraphics().drawImage(newImage, 0, 0, saver);
|
||||||
|
saver.saveImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class NumberInputVerifier extends InputVerifier {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean verify(JComponent input) {
|
||||||
|
String text = ((JTextField) input).getText();
|
||||||
|
try {
|
||||||
|
Integer.parseInt(text);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ImageSaver implements ImageObserver {
|
||||||
|
|
||||||
|
private String filename;
|
||||||
|
private BufferedImage image;
|
||||||
|
private String formatName;
|
||||||
|
|
||||||
|
public ImageSaver(String filename, BufferedImage image) {
|
||||||
|
this.filename = filename;
|
||||||
|
this.image = image;
|
||||||
|
this.formatName = getExtension(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean imageUpdate(Image img, int infoflags, int x, int y,
|
||||||
|
int width, int height) {
|
||||||
|
if (infoflags == ImageObserver.ERROR) {
|
||||||
|
if (!errorNotified) {
|
||||||
|
errorNotified = true;
|
||||||
|
JOptionPane.showMessageDialog(ImageWitchGui.this,
|
||||||
|
"<html>Unable to resize file: <br>" + filename +
|
||||||
|
"<br><br>Other files may be affected.",
|
||||||
|
"Resize Error",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveImage();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveImage() {
|
||||||
|
File file = new File(filename);
|
||||||
|
try {
|
||||||
|
ImageIO.write(image, formatName, file);
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (!errorNotified) {
|
||||||
|
errorNotified = true;
|
||||||
|
JOptionPane.showMessageDialog(ImageWitchGui.this,
|
||||||
|
"<html>Unable to save file: <br>" + filename +
|
||||||
|
"<br><br>Other files may be affected.",
|
||||||
|
"Save Error",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FieldListener implements DocumentListener {
|
||||||
|
|
||||||
|
private JTextField field;
|
||||||
|
|
||||||
|
public FieldListener(JTextField field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void update() {
|
||||||
|
Integer value = 0;
|
||||||
|
|
||||||
|
if (!field.getText().isBlank()) {
|
||||||
|
value = Integer.parseInt(field.getText());
|
||||||
|
}
|
||||||
|
if (field == heightField) {
|
||||||
|
maxHeight = value;
|
||||||
|
} else {
|
||||||
|
maxWidth = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insertUpdate(DocumentEvent e) {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeUpdate(DocumentEvent e) {
|
||||||
|
update();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void changedUpdate(DocumentEvent e) {
|
||||||
|
update();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user