如何获得调整大小的图像的新高度和宽度?

时间:2013-08-05 10:39:51

标签: java swing

我正在尝试保存新调整大小的图像,但我完全没有任何想法获得新的高度&图像的宽度或轴。 如果有人知道,那么我会非常感激。

调整图像大小或缩放图像的代码如下:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ImageViewer {

    public static void main(String[] args) {
        new ImageViewer();
    }

    public ImageViewer() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new ViewPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ViewPane extends JPanel {

        public ViewPane() {
            setLayout(null);
            ImagePane imagePane = new ImagePane();
            imagePane.setSize(imagePane.getPreferredSize());
            imagePane.setLocation(0, 0);
            add(imagePane);
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

    public static class ImagePane extends JPanel {

        private BufferedImage bg;
        private BufferedImage scaled;

        public ImagePane() {
            try {
                bg = ImageIO.read(new File("src.jpg"));
                scaled = getScaledInstanceToFit(bg, new Dimension(100, 100));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            setBackground(Color.BLACK);

            MouseHandler handler = new MouseHandler();
            addMouseListener(handler);
            addMouseMotionListener(handler);
        }

        @Override
        public Dimension getPreferredSize() {
            return bg == null ? new Dimension(200, 200) : new Dimension(scaled.getWidth(), scaled.getHeight());
        }

        @Override
        public void invalidate() {
            super.invalidate();
            scaled = getScaledInstanceToFit(bg, getSize());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int x = (getWidth() - scaled.getWidth()) / 2;
            int y = (getHeight() - scaled.getHeight()) / 2;
            g2d.drawImage(scaled, x, y, this);
            g2d.dispose();
        }

        public enum MouseAction {

            Move(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)),
            ResizeSouth(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)),
            ResizeNorth(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)),
            ResizeEast(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR)),
            ResizeWest(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)),
            ResizeNorthEast(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR)),
            ResizeNorthWest(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR)),
            ResizeSouthEast(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR)),
            ResizeSouthWest(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));

            private Cursor cursor;

            private MouseAction(Cursor cursor) {
                this.cursor = cursor;
            }

            public Cursor getCursor() {
                return cursor;
            }

        }

        public class MouseHandler extends MouseAdapter {

            private MouseAction action;
            private Point clickPoint;
            private Point offset;
            private boolean ignoreMoves;

            protected void updateAction(MouseEvent e) {
                int x = e.getX();
                int y = e.getY();

                int width = getWidth();
                int height = getHeight();

                if (x < 10 && y < 10) {
                    action = MouseAction.ResizeNorthWest;
                } else if (x > width - 10 && y < 10) {
                    action = MouseAction.ResizeNorthWest;
                } else if (y < 10) {
                    action = MouseAction.ResizeNorth;
                } else if (x < 10 && y > height - 10) {
                    action = MouseAction.ResizeSouthWest;
                } else if (x > width - 10 && y > height - 10) {
                    action = MouseAction.ResizeSouthEast;
                } else if (y > height - 10) {
                    action = MouseAction.ResizeSouth;
                } else if (x < 10) {
                    action = MouseAction.ResizeWest;
                } else if (x > width - 10) {
                    action = MouseAction.ResizeEast;
                } else {
                    action = MouseAction.Move;
                }
                setCursor(action.getCursor());
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                if (!ignoreMoves) {
                    updateAction(e);
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {
                updateAction(e);
                ignoreMoves = true;
                clickPoint = e.getPoint();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                clickPoint = null;
                ignoreMoves = false;
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                switch (action) {
                    case Move: {
                        Point p = e.getPoint();
                        p.x -= clickPoint.x;
                        p.y -= clickPoint.y;
                        p = SwingUtilities.convertPoint(ImagePane.this, p, getParent());
                        setLocation(p);
                    }
                    break;
                    case ResizeWest: {
                        Point p = e.getPoint();
                        int xDelta = p.x - clickPoint.x;
                        int width = getWidth() - xDelta;
                        int x = getX() + xDelta;
                        setSize(width, getHeight());
                        setLocation(x, getY());
                        revalidate();
                    }
                    break;
                    case ResizeEast: {
                        Point p = e.getPoint();
                        int xDelta = p.x - clickPoint.x;
                        int width = getWidth() + xDelta;
                        setSize(width, getHeight());
                        revalidate();
                        clickPoint = p;
                    }
                    break;
                    case ResizeNorth: {
                        Point p = e.getPoint();
                        int yDelta = p.y - clickPoint.y;
                        int height = getHeight() - yDelta;
                        int y = getY() + yDelta;
                        setSize(getWidth(), height);
                        setLocation(getX(), y);
                        revalidate();
                    }
                    break;
                    case ResizeSouth: {
                        Point p = e.getPoint();
                        int yDelta = p.y - clickPoint.y;
                        int height = getHeight() + yDelta;
                        setSize(getWidth(), height);
                        revalidate();
                        clickPoint = p;
                    }
                    break;
                }
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }

        }

    }

    public static BufferedImage getScaledInstanceToFit(BufferedImage img, Dimension size) {
        double scaleFactor = getScaleFactorToFit(img, size);
        return getScaledInstance(img, scaleFactor);
    }

    public static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor) {
        BufferedImage imgBuffer = null;
        imgBuffer = getScaledInstance(img, dScaleFactor, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        return imgBuffer;
    }

    protected static BufferedImage getScaledInstance(BufferedImage img, double dScaleFactor, Object hint) {
        BufferedImage imgScale = img;
        int iImageWidth = (int) Math.round(img.getWidth() * dScaleFactor);
        int iImageHeight = (int) Math.round(img.getHeight() * dScaleFactor);

        if (dScaleFactor <= 1.0d) {
            imgScale = getScaledDownInstance(img, iImageWidth, iImageHeight, hint);
        } else {
            imgScale = getScaledUpInstance(img, iImageWidth, iImageHeight, hint);
        }
        return imgScale;
    }

    protected static BufferedImage getScaledDownInstance(BufferedImage img,
            int targetWidth,
            int targetHeight,
            Object hint) {

//        System.out.println("Scale down...");
        int type = (img.getTransparency() == Transparency.OPAQUE)
                ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;

        BufferedImage ret = (BufferedImage) img;

        if (targetHeight > 0 || targetWidth > 0) {
            int w, h;
            // Use multi-step technique: start with original size, then
            // scale down in multiple passes with drawImage()
            // until the target size is reached
            w = img.getWidth();
            h = img.getHeight();

            do {
                if (w > targetWidth) {
                    w /= 2;
                    if (w < targetWidth) {
                        w = targetWidth;
                    }
                }

                if (h > targetHeight) {
                    h /= 2;
                    if (h < targetHeight) {
                        h = targetHeight;
                    }
                }

                BufferedImage tmp = new BufferedImage(Math.max(w, 1), Math.max(h, 1), type);
                Graphics2D g2 = tmp.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
                g2.drawImage(ret, 0, 0, w, h, null);
                g2.dispose();

                ret = tmp;
            } while (w != targetWidth || h != targetHeight);
        } else {
            ret = new BufferedImage(1, 1, type);
        }

        return ret;
    }

    protected static BufferedImage getScaledUpInstance(BufferedImage img,
            int targetWidth,
            int targetHeight,
            Object hint) {

        int type = BufferedImage.TYPE_INT_ARGB;

        BufferedImage ret = (BufferedImage) img;
        int w, h;
        w = img.getWidth();
        h = img.getHeight();

        do {
            if (w < targetWidth) {
                w *= 2;
                if (w > targetWidth) {
                    w = targetWidth;
                }
            }

            if (h < targetHeight) {
                h *= 2;
                if (h > targetHeight) {
                    h = targetHeight;
                }
            }

            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();

            ret = tmp;
            tmp = null;
        } while (w != targetWidth || h != targetHeight);

        return ret;
    }

    public static double getScaleFactorToFit(BufferedImage img, Dimension size) {
        double dScale = 1;
        if (img != null) {
            int imageWidth = img.getWidth();
            int imageHeight = img.getHeight();
            dScale = getScaleFactorToFit(new Dimension(imageWidth, imageHeight), size);
        }
        return dScale;
    }

    public static double getScaleFactorToFit(Dimension original, Dimension toFit) {
        double dScale = 1d;
        if (original != null && toFit != null) {
            double dScaleWidth = getScaleFactor(original.width, toFit.width);
            double dScaleHeight = getScaleFactor(original.height, toFit.height);
            dScale = Math.min(dScaleHeight, dScaleWidth);
        }
        return dScale;
    }

    public static double getScaleFactor(int iMasterSize, int iTargetSize) {
        double dScale = 1;
        if (iMasterSize > iTargetSize) {
            dScale = (double) iTargetSize / (double) iMasterSize;
        } else {
            dScale = (double) iTargetSize / (double) iMasterSize;
        }
        return dScale;
    }
}

我也可以轻松移动我的图像并且还可以改变尺寸,但是现在我想要保存新的图像,但我必须首先获得它的新高度和宽度,如果我能得到它然后我会轻松保存它

  

任何人都可以帮助我???

1 个答案:

答案 0 :(得分:1)

根据你想要实现的目标,我很想在ImagePane上添加一个方法(类似于save ...

public void save(String path, String name) throws IOException {
    if (scaled != null) {  
        name += scaled.getWidth() + "x" + scaled.getHeight();
        ImageIO.write(scaled, "png", new File(path + File.separator + name + ".png"));
    } else {
        throw new NullPointerException("Scaled instance is null");
    }
}

查看Writing/Saving an Image

你也可以简单地根据ImagePane的状态传回一个缩放的实例......

public BufferedImage getScaledInstance() {
    return getScaledInstanceToFit(bg, getSize());
}

我不会返回scaled对象,因为如果你可以帮助它,你不希望别人搞乱它......