android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具

最近开发android,在网上发现一个很好的工具,可以自动生成drawable文件夹下的图片,具体运行效果如下图所示
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第1张图片
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第2张图片

现在分享一下生成过程
eclispe创建一个java环境,结构如下
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第3张图片

现将三个类的源码分享一下
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包
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第4张图片
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第5张图片

下载exe4j,安装,将jar转换为.exe文件,根据系统版本位数下载32位或64位的exe4j
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第6张图片
next
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第7张图片
next
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第8张图片
填写需要生成的文件名与输出位置
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第9张图片
如果是64位系统,点击Advance Options,选择64-bit,勾选Generate 64-bit
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第10张图片
选择生成的jar
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第11张图片
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第12张图片
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第13张图片
然后一路next
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第14张图片
Exit
就可以直接运行生成的.exe文件
android 自动生成ldpi, mdpi, hdpi, xhdpi, xxhdpi, xxxhdpi图片的工具_第15张图片

你可能感兴趣的:(android,drawable生成)