android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具
2015-12-14 13:34
148 查看
最近开发android,在网上发现一个很好的工具,可以自动生成drawable文件夹下的图片,具体运行效果如下图所示
现在分享一下生成过程
eclispe创建一个java环境,结构如下
现将三个类的源码分享一下
AndroidDrawableFactory.java
ImageUtils.java
Main.java
导出jar包
下载exe4j,安装,将jar转换为.exe文件,根据系统版本位数下载32位或64位的exe4j
next
next
填写需要生成的文件名与输出位置
如果是64位系统,点击Advance Options,选择64-bit,勾选Generate 64-bit
选择生成的jar
然后一路next
Exit
就可以直接运行生成的.exe文件
现在分享一下生成过程
eclispe创建一个java环境,结构如下
现将三个类的源码分享一下
AndroidDrawableFactory.java
public class AndroidDrawableFactory { //constants public static final String[] DENSITIES = {"ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"}; public static final double[] DENSITY_MULTIPLIERS = {.75, 1, 1.5, 2, 3, 4}; public static void main(String... args) { initLaF(); Main mainWindow = new Main(); mainWindow.pack(); mainWindow.setTitle("Android Drawable Factory"); mainWindow.setLocationRelativeTo(null); mainWindow.setResizable(false); mainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainWindow.setVisible(true); } private static void initLaF() { UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels(); try { boolean hasGTK = false; for(UIManager.LookAndFeelInfo info : lafs) { if(info.getName().equals("GTK+")) { hasGTK = true; break; } } if(hasGTK) { UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); } else UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch(UnsupportedLookAndFeelException e){e.printStackTrace();} catch(ClassNotFoundException e){e.printStackTrace();} catch(InstantiationException e){e.printStackTrace();} catch(IllegalAccessException e){e.printStackTrace();} }
ImageUtils.java
public class ImageUtils { public static double getAspectRatio(BufferedImage img, int newWidth, int newHeight) { int imgWidth = img.getWidth(null); int imgHeight = img.getHeight(null); double xRatio = (double) newWidth / (double) imgWidth; double yRatio = (double) newHeight / (double) imgHeight; return Math.min(xRatio, yRatio); } public static Image resizeImage(BufferedImage bImg, int newWidth, int newHeight) throws FileNotFoundException, IOException { double ratio = getAspectRatio(bImg, newWidth, newHeight); newWidth = (int) (bImg.getWidth(null) * ratio); newHeight = (int) (bImg.getHeight(null) * ratio); Image resizedImage = bImg.getScaledInstance(newWidth, newHeight, Image.SCALE_SMOOTH); return resizedImage; } public static int getMaxWidth(File img) throws FileNotFoundException, IOException { BufferedImage bImg= ImageIO.read(new FileInputStream(img)); int width = bImg.getWidth(); int height = bImg.getHeight(); return Math.max(width, height); }
Main.java
@SuppressWarnings("serial") public class Main extends JFrame{ //Instance parameters JLabel imageCanvas; //canvas that store the image to modify JFileChooser imageChooser, projectPathChooser; //JFileChooser for the source image and project path JTextField projectPathField, sourceSizeTextField; //fields to store projectPath and source image size JButton projectPathButton, createButton; //Buttons to open the path chooser and to start drawables conversion JLabel sourceDensityLabel, sourceSizeLabel; //labels for source density and source size fields JComboBox<String> sourceDensityComboBox; //list of available densities LinkedHashMap<String, JCheckBox> densitiesCheckBox; //HashMap that stores the available density checkboxes JPanel mainPanel, densitiesPanel; //panel containing checkboxes private File lastUsedSourceDirectory; private File lastUsedProjectDirectory; //JProgressBar progressBar; File sourceImg; //source Image File object String sourceFileName; //source file name BufferedImage bufferedSource; //Source image BufferedImage object public Main() { super("Main Window"); initUI(); //initialize ui elements initListeners(); //initialize ui event listeners } @SuppressWarnings({ "unchecked", "rawtypes" }) private void initUI() { //create components imageCanvas = new JLabel(); //image to be used imageCanvas.setIcon(new ImageIcon(getClass().getResource("/placeholder.png"))); imageCanvas.setBackground(Color.decode("#33B5E5")); imageCanvas.setBorder(BorderFactory.createLineBorder(Color.black)); imageCanvas.setToolTipText("Click to select an Image"); projectPathChooser = new JFileChooser(); //Launch directory selection projectPathField = new JTextField(); //Retains the path selected with JFileChooser projectPathField.setEditable(false); projectPathField.setText("project path"); projectPathButton = new JButton("Browse"); //Button that launch JFileChooser sourceDensityLabel = new JLabel("Source Density"); //Label for the source density field sourceDensityComboBox = new JComboBox<String>(AndroidDrawableFactory.DENSITIES); //selector for the source density sourceSizeLabel = new JLabel("Source Size"); //Label for source image's size sourceSizeTextField = new JTextField(); //Field for source image's size sourceSizeTextField.setEditable(false); densitiesCheckBox = new LinkedHashMap<String, JCheckBox>(); //checkbox Map with densities createButton = new JButton("make"); //button to begin drawable conversion densitiesPanel = new JPanel(); //initialize checkboxes for(int i = 0; i < AndroidDrawableFactory.DENSITIES.length; i++) { String density = AndroidDrawableFactory.DENSITIES[i]; densitiesCheckBox.put(density, new JCheckBox(density)); } for(JCheckBox e : densitiesCheckBox.values()) { e.setSelected(true); densitiesPanel.add(e); } densitiesPanel.add(createButton); //create and set LayoutManager this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS)); mainPanel = new JPanel(); GroupLayout gp = new GroupLayout(mainPanel); gp.setAutoCreateContainerGaps(true); gp.setAutoCreateGaps(true); mainPanel.setLayout(gp); //set alignment criteria GroupLayout.Alignment hAlign = GroupLayout.Alignment.TRAILING; GroupLayout.Alignment vAlign = GroupLayout.Alignment.BASELINE; //add component into layout //set horizontal group gp.setHorizontalGroup(gp.createSequentialGroup() .addGroup(gp.createParallelGroup(hAlign) .addComponent(imageCanvas, 80, 80, 80)) .addGroup(gp.createParallelGroup(hAlign) .addComponent(projectPathField, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE) //.addComponent(projectPathField) .addComponent(sourceDensityLabel, Alignment.LEADING) .addComponent(sourceSizeLabel, Alignment.LEADING)) .addGroup(gp.createParallelGroup(hAlign) .addComponent(projectPathButton) .addComponent(sourceDensityComboBox,GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE) .addComponent(sourceSizeTextField,GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE, 50)) ); //set vertical group gp.setVerticalGroup(gp.createSequentialGroup() .addGroup(gp.createParallelGroup(vAlign) .addComponent(imageCanvas, 80, 80, 80) .addGroup(gp.createSequentialGroup() .addGroup(gp.createParallelGroup(vAlign) .addComponent(projectPathField) .addComponent(projectPathButton)) .addGroup(gp.createParallelGroup(vAlign) .addComponent(sourceDensityLabel) .addComponent(sourceDensityComboBox)) .addGroup(gp.createParallelGroup(vAlign) .addComponent(sourceSizeLabel) .addComponent(sourceSizeTextField))) ) ); this.add(mainPanel); this.add(densitiesPanel); } private void initListeners() { //Source Image click listener imageCanvas.addMouseListener(new MouseListener(){ public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub JFileChooser imageChooser = new JFileChooser(); if (lastUsedSourceDirectory != null) { imageChooser.setCurrentDirectory(lastUsedSourceDirectory); } imageChooser.setDialogTitle("Select an image"); imageChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); imageChooser.setFileFilter(new FileFilter(){ @Override public boolean accept(File file) { if(file.getName().endsWith(".jpg") || file.getName().endsWith(".png") || file.isDirectory()) { return true; } else return false; } @Override public String getDescription() { return "Images (.jpg;.png)"; } }); imageChooser.setAcceptAllFileFilterUsed(false); switch(imageChooser.showOpenDialog(imageCanvas)) { case(JFileChooser.APPROVE_OPTION): try { sourceImg = new File(imageChooser.getSelectedFile().getPath()); lastUsedSourceDirectory = sourceImg.getParentFile(); sourceFileName = sourceImg.getName(); bufferedSource = ImageIO.read(sourceImg); Image sourceResized = ImageUtils.resizeImage(bufferedSource, 80, 80); imageCanvas.setIcon(new ImageIcon(sourceResized)); sourceSizeTextField.setText(Integer.toString(ImageUtils.getMaxWidth(sourceImg))); } catch (IOException e) { e.printStackTrace(); } break; } } public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } }); projectPathButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub projectPathChooser = new JFileChooser(); if (lastUsedProjectDirectory != null) { projectPathChooser.setCurrentDirectory(lastUsedProjectDirectory); } projectPathChooser.setDialogTitle("Project root directory of your app"); projectPathChooser.setAcceptAllFileFilterUsed(false); projectPathChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); if(projectPathChooser.showOpenDialog(projectPathButton) == JFileChooser.APPROVE_OPTION) { projectPathField.setText(projectPathChooser.getSelectedFile().getPath()); lastUsedProjectDirectory = projectPathChooser.getSelectedFile(); } } }); //"Make" button action listener createButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub if(bufferedSource == null || projectPathField.getText().equals("project path")) { JOptionPane.showMessageDialog(rootPane, "Please select an image and a valid project path", "Error", JOptionPane.ERROR_MESSAGE); } else { //disable make button createButton.setEnabled(false); resizeThread = new Thread(resizeRunnable); resizeThread.start(); } } }); } Thread resizeThread; Runnable resizeRunnable = new Runnable(){ public void run() { // TODO Auto-generated method stub //handy references to AndroidDrawableFactory.class constants String[] densities = AndroidDrawableFactory.DENSITIES; double[] density_ratio = AndroidDrawableFactory.DENSITY_MULTIPLIERS; //create hashmap with density and density ratio HashMap<String, Double> densityMap = new HashMap<String, Double>(); for(int i = 0; i < densities.length; i++) { densityMap.put(densities[i], density_ratio[i]); } double targetDensity = densityMap.get(sourceDensityComboBox.getSelectedItem().toString()); for(Map.Entry<String, Double> e : densityMap.entrySet()) { JCheckBox singleDensity = densitiesCheckBox.get(e.getKey()); String projectPath = projectPathField.getText(); File projectResourceRoot = new File(projectPath); /*if (!"res".equals(projectResourceRoot.getName())) { projectResourceRoot = new File(projectResourceRoot, "res"); }*/ if(singleDensity.isSelected()) { String folderName = "drawable-" + e.getKey(); double densityRatio = e.getValue(); int newWidth = Math.round((float)(bufferedSource.getWidth() / targetDensity * densityRatio)); int newHeight = Math.round((float)(bufferedSource.getHeight() / targetDensity * densityRatio)); try { Image newImg = ImageUtils.resizeImage(bufferedSource, newWidth, newHeight); File targetDir = new File(projectResourceRoot, folderName); boolean dirExists = false; //check if project dir exists, if not create it dirExists = targetDir.exists() || targetDir.mkdir(); if(dirExists) { BufferedImage bufImg = new BufferedImage(newImg.getWidth(null), newImg.getHeight(null), BufferedImage.TYPE_INT_ARGB); Graphics2D img2D = bufImg.createGraphics(); img2D.drawImage(newImg, null, null); RenderedImage targetImg = (RenderedImage) bufImg; File newFile = new File(targetDir + File.separator + sourceFileName); ImageIO.write(targetImg, "png", newFile); } } catch (IOException e1) { e1.printStackTrace(); } } } javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { // TODO Auto-generated method stub JOptionPane.showMessageDialog(getContentPane(), "Resize Completed!", "Completed", JOptionPane.INFORMATION_MESSAGE); createButton.setEnabled(true); } }); } };
导出jar包
下载exe4j,安装,将jar转换为.exe文件,根据系统版本位数下载32位或64位的exe4j
next
next
填写需要生成的文件名与输出位置
如果是64位系统,点击Advance Options,选择64-bit,勾选Generate 64-bit
选择生成的jar
然后一路next
Exit
就可以直接运行生成的.exe文件
相关文章推荐
- Android Context完全解析,你所不知道的Context的各种细节
- Android消息机制源码解析(二)——消息的执行者Handler
- Android 欢迎页TimerTask的使用,及注意事项
- 每个Android开发者必须知道的内存管理知识
- 强大的Android参数模拟器,自由修改手机型号、SDK版本号等信息
- android Xutile ,Voller 对比
- android四大组件
- Android如何获得手机power_profile.xml文件
- Android 控件之RatingBar评分条(五星)自定义样式
- android studio 如何修改包名
- Android Studio 常用快捷键
- Android开源框架
- android加混淆 方式与坑
- 上拉刷新 下拉加载更多-PullToRefreshListView的简介
- android_studio多渠道打包
- Android编程之json解析实例详解
- 解决android有的手机拍照后上传图片被旋转的问题
- Android EditText 不弹出软键盘
- Android测试工具详解
- 安卓开发之安卓反编译