package AndroidDevToolbox;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tab;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleButton;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import org.apache.commons.io.FilenameUtils;
import org.imgscalr.Scalr;
import utils.AppConfig;
import utils.FileHelper;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.ResourceBundle;
public class ImageResizeController extends BaseController implements Initializable {
public Tab singleResizeTab;
public Tab batchResizeTab;
public Button fileSelectBrowseBtn;
public TextField singleFileTextField;
public GridPane imageFileInfoPane;
public GridPane selectImageNoticePane;
public ImageView fileInfoImageView;
public Label imageWidthLabel;
public Label imageHeightLabel;
public Label fileSizeLabel;
public ToggleButton densityBtnMdpi;
public ToggleButton densityBtnHdpi;
public ToggleButton densityBtnXHdpi;
public ToggleButton densityBtnXXHdpi;
public Button outputSelectBrowseBtn;
public TextField outputFolderTextField;
public Button imageResizeBtn;
public Button inputFolderSelectBrowseBtn;
public TextField batchFileTextField;
public GridPane folderInfoPane;
public GridPane selectFolderNoticePane;
public Label folderNumOfImageLabel;
private final String FIXED_SEPARATOR = "#!#";
private enum RESIZE_MODE {
SINGLE,
BATCH
}
private enum DENSITY {
M_DPI,
H_DPI,
XH_DPI,
XXH_DPI
}
// mdpi hdpi xhdpi xxhdpi
private static final float[] DENSITY_FACTORS = {
1.0f, 1.5f, 2.0f, 3.0f
} ;
private DENSITY density;
private RESIZE_MODE resizeMode;
private ResourceBundle resourceBundle;
private ImageResizeService imageResizeService;
private String outputFolderPath;
private String inputFolderPath;
private String imageFilePath;
private boolean imageFileSelected;
private boolean outputFolderSelected;
private boolean inputFolderSelected;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
this.resourceBundle = resourceBundle;
resizeMode = RESIZE_MODE.SINGLE;
density = DENSITY.M_DPI;
// fileInfoImageView.fitWidthProperty().bind(imageFileInfoPane.widthProperty());
// fileInfoImageView.fitHeightProperty().bind(imageFileInfoPane.heightProperty());
updateFileInfoContent(null);
updateFolderInfoContent(null);
imageResizeService = new ImageResizeService();
}
public void browseForImageFile() {
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle(resourceBundle.getString("ResizeSelectImageFile"));
fileChooser.getExtensionFilters().addAll(
new FileChooser.ExtensionFilter("All Images", "*.*"),
new FileChooser.ExtensionFilter("JPG", "*.jpg"),
new FileChooser.ExtensionFilter("PNG", "*.png")
);
// open file dialog
File file = fileChooser.showOpenDialog(fileSelectBrowseBtn.getScene().getWindow());
if (file != null) {
singleFileTextField.setText(file.getPath());
imageFilePath = file.getPath();
imageFileSelected = true;
updateStartBtnState();
updateFileInfoContent(file);
}
}
public void setSourceDensity(MouseEvent event) {
if (event.getSource() == densityBtnMdpi) {
densityBtnMdpi.setSelected(true);
density = DENSITY.M_DPI;
} else if (event.getSource() == densityBtnHdpi) {
densityBtnHdpi.setSelected(true);
density = DENSITY.H_DPI;
} else if (event.getSource() == densityBtnXHdpi) {
densityBtnXHdpi.setSelected(true);
density = DENSITY.XH_DPI;
} else if (event.getSource() == densityBtnXXHdpi) {
densityBtnXXHdpi.setSelected(true);
density = DENSITY.XXH_DPI;
}
}
public void browseForInputFolder() {
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle(resourceBundle.getString("ResizeSelectInputFolder"));
File inputFolder = directoryChooser.showDialog(inputFolderSelectBrowseBtn.getScene().getWindow());
if (inputFolder != null) {
batchFileTextField.setText(inputFolder.getPath());
inputFolderSelected = true;
inputFolderPath = inputFolder.getPath();
updateStartBtnState();
updateFolderInfoContent(inputFolder);
}
}
public void browseForOutputFolder() {
DirectoryChooser directoryChooser = new DirectoryChooser();
directoryChooser.setTitle(resourceBundle.getString("ResizeSelectOutputFolder"));
File outputFolder = directoryChooser.showDialog(outputSelectBrowseBtn.getScene().getWindow());
if (outputFolder != null) {
outputFolderTextField.setText(outputFolder.getPath());
outputFolderSelected = true;
outputFolderPath = outputFolder.getPath();
updateStartBtnState();
}
}
public void startResizeImage() {
imageResizeService.restart();
}
public void tabOnSelectionChanged() {
if (singleResizeTab.isSelected()) {
resizeMode = RESIZE_MODE.SINGLE;
} else {
resizeMode = RESIZE_MODE.BATCH;
}
updateStartBtnState();
}
private void updateFolderInfoContent(File file) {
if (file == null) {
if (folderInfoPane != null && selectFolderNoticePane != null) {
folderInfoPane.setVisible(false);
selectFolderNoticePane.setVisible(true);
}
return;
}
folderInfoPane.setVisible(true);
selectFolderNoticePane.setVisible(false);
int numOfImageFiles = 0;
File[] files = file.listFiles();
for (File folderFile : files) {
if (isImageFileExtension(folderFile.getName())) {
numOfImageFiles++;
}
}
folderNumOfImageLabel.setText(
resourceBundle.getString("ResizeFolderImageCount") + " " + numOfImageFiles);
}
private boolean isImageFileExtension(String fileName) {
return FilenameUtils.getExtension(fileName).equalsIgnoreCase("JPG")
|| FilenameUtils.getExtension(fileName).equalsIgnoreCase("PNG");
}
private void updateFileInfoContent(File file) {
if (file == null) {
if (imageFileInfoPane != null && selectImageNoticePane != null) {
imageFileInfoPane.setVisible(false);
selectImageNoticePane.setVisible(true);
}
return;
}
imageFileInfoPane.setVisible(true);
selectImageNoticePane.setVisible(false);
Image image = new Image("file:" + file.getPath());
fileInfoImageView.setImage(image);
imageWidthLabel.setText(
resourceBundle.getString("ResizeFileWidth") + " " + (int)image.getWidth() + "px");
imageHeightLabel.setText(
resourceBundle.getString("ResizeFileHeight") + " " + (int)image.getHeight() + "px");
fileSizeLabel.setText(
resourceBundle.getString("ResizeFileSize") + " " +
FileHelper.readableFileSize(file.length()));
}
private void updateStartBtnState() {
if (resizeMode == RESIZE_MODE.SINGLE) {
if (imageFileSelected && outputFolderSelected) {
imageResizeBtn.setDisable(false);
} else {
if (imageResizeBtn != null) {
imageResizeBtn.setDisable(true);
}
}
} else if (resizeMode == RESIZE_MODE.BATCH) {
if (inputFolderSelected && outputFolderSelected) {
imageResizeBtn.setDisable(false);
} else {
if (imageResizeBtn != null) {
imageResizeBtn.setDisable(true);
}
}
}
}
private class ImageResizeService extends Service<Void> {
@Override
protected Task<Void> createTask() {
Task task = new Task<Void>() {
@Override
protected Void call() throws Exception {
updateMessage(resourceBundle.getString("ResizeStarted"));
// create folders
String rootFolder = outputFolderPath + File.separator +
AppConfig.FOLDER_RESIZE_PREFIX + "_" + System.currentTimeMillis();
FileHelper.makeFolder(rootFolder);
String mdpiPath = rootFolder + File.separator + AppConfig.FOLDER_DRAWABLE_MDPI;
String hdpiPath = rootFolder + File.separator + AppConfig.FOLDER_DRAWABLE_HDPI;
String xhdpiPath = rootFolder + File.separator + AppConfig.FOLDER_DRAWABLE_XHDPI;
String xxhdpiPath = rootFolder + File.separator + AppConfig.FOLDER_DRAWABLE_XXHDPI;
FileHelper.makeFolder(mdpiPath);
FileHelper.makeFolder(hdpiPath);
FileHelper.makeFolder(xhdpiPath);
FileHelper.makeFolder(xxhdpiPath);
ArrayList<String> targetFolders = new ArrayList<String>();
targetFolders.add(mdpiPath + FIXED_SEPARATOR + DENSITY_FACTORS[DENSITY.M_DPI.ordinal()]);
targetFolders.add(hdpiPath + FIXED_SEPARATOR + DENSITY_FACTORS[DENSITY.H_DPI.ordinal()]);
targetFolders.add(xhdpiPath + FIXED_SEPARATOR + DENSITY_FACTORS[DENSITY.XH_DPI.ordinal()]);
targetFolders.add(xxhdpiPath + FIXED_SEPARATOR + DENSITY_FACTORS[DENSITY.XXH_DPI.ordinal()]);
float sourceDensityFactor = DENSITY_FACTORS[density.ordinal()];
String sourceDensityFolder = "";
if (density == DENSITY.M_DPI) {
sourceDensityFolder = mdpiPath;
} else if (density == DENSITY.H_DPI) {
sourceDensityFolder = hdpiPath;
} else if (density == DENSITY.XH_DPI) {
sourceDensityFolder = xhdpiPath;
} else if (density == DENSITY.XXH_DPI) {
sourceDensityFolder = xxhdpiPath;
}
targetFolders.remove(sourceDensityFolder + FIXED_SEPARATOR + sourceDensityFactor);
// copy original image to its density folder
if (resizeMode == RESIZE_MODE.SINGLE) {
System.out.println(imageFilePath);
String fileName = new File(imageFilePath).getName();
FileHelper.copyFile(imageFilePath
, sourceDensityFolder + File.separator
+ fileName.replace(" ", "_").toLowerCase());
} else if (resizeMode == RESIZE_MODE.BATCH) {
File[] Files = new File(inputFolderPath).listFiles();
for (File folderFile : Files) {
if (isImageFileExtension(folderFile.getName())) {
FileHelper.copyFile(folderFile.getPath()
, sourceDensityFolder + File.separator
+ folderFile.getName().replace(" ", "_").toLowerCase());
}
}
}
// resize into different densities
File[] sourceDirFiles = new File(sourceDensityFolder).listFiles();
int numOfFiles = sourceDirFiles.length;
int count = 1;
for (File file : sourceDirFiles) {
String fileName = file.getName();
String fileExt = FilenameUtils.getExtension(fileName);
String sourceFilePath = sourceDensityFolder + File.separator + fileName;
updateMessage(
resourceBundle.getString("ResizeProgress") + " " + fileName
+ " (" + count + " / " + numOfFiles + ")");
BufferedImage bufferedImage = null;
try {
bufferedImage = ImageIO.read(new File(sourceFilePath));
} catch (Exception e) {
e.printStackTrace();
continue;
}
if (bufferedImage == null) {
continue;
}
float sourceWidth = bufferedImage.getWidth();
float sourceHeight = bufferedImage.getHeight();
for (String targetFolderAndDensity : targetFolders) {
String[] targetFolderDensity = targetFolderAndDensity.split(FIXED_SEPARATOR);
String folder = targetFolderDensity[0];
String targetDensityFactor = targetFolderDensity[1];
int targetWidth = (int) Math.ceil(sourceWidth / sourceDensityFactor
* Float.parseFloat(targetDensityFactor));
int targetHeight = (int) Math.ceil(sourceHeight / sourceDensityFactor
* Float.parseFloat(targetDensityFactor));
BufferedImage resizedImage = Scalr.resize(bufferedImage
, Scalr.Method.QUALITY
, targetWidth
, targetHeight);
ImageIO.write(resizedImage, fileExt
, new File(folder + File.separator
+ fileName.replace(" ", "_").toLowerCase()));
}
count++;
}
updateMessage(resourceBundle.getString("ResizeCompleted"));
return null;
}
};
getStatusBarLabel().textProperty().bind(task.messageProperty());
return task;
}
@Override
protected void succeeded() {
super.succeeded();
getStatusBarLabel().textProperty().unbind();
if (getBackgroundTaskExecutionListener() != null) {
getBackgroundTaskExecutionListener().taskComplete();
}
imageResizeBtn.setDisable(false);
inputFolderSelectBrowseBtn.setDisable(false);
fileSelectBrowseBtn.setDisable(false);
outputSelectBrowseBtn.setDisable(false);
densityBtnMdpi.setDisable(false);
densityBtnHdpi.setDisable(false);
densityBtnXHdpi.setDisable(false);
densityBtnXXHdpi.setDisable(false);
singleResizeTab.setDisable(false);
batchResizeTab.setDisable(false);
}
@Override
protected void running() {
super.running();
if (getBackgroundTaskExecutionListener() != null) {
getBackgroundTaskExecutionListener().taskStart();
}
imageResizeBtn.setDisable(true);
inputFolderSelectBrowseBtn.setDisable(true);
fileSelectBrowseBtn.setDisable(true);
outputSelectBrowseBtn.setDisable(true);
densityBtnMdpi.setDisable(true);
densityBtnHdpi.setDisable(true);
densityBtnXHdpi.setDisable(true);
densityBtnXXHdpi.setDisable(true);
singleResizeTab.setDisable(true);
batchResizeTab.setDisable(true);
}
}
}