如何使图像在swing中伸展?

目前我正在通过BufferedImage在Jframe swing组件中加载图像。 图像加载成功,但我想让图像可伸缩,当用户选择图像的右下角并尝试resize然后它将成为可能。 &用户可以保存resize的图像,但如何做到这一点我没有确切的想法。 所以如果有人引导我,那么我会非常感激。 我不想要整个代码,但我只是想要指导和提示。

我的代码如下:

import java.io.File; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.color.ColorSpace; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.image.BufferedImage; import java.awt.image.RescaleOp; import javax.imageio.ImageIO; @SuppressWarnings("serial") public class Brighten extends JPanel{ @Override public void paintComponent(Graphics g){ Graphics2D g2d=(Graphics2D)g; try{ //reading image data from file BufferedImage src=ImageIO.read(new File("src.jpg")); /* passing source image and brightening by 50%-value of 1.0f means original brightness */ BufferedImage dest=changeBrightness(src,1.5f); //drawing new image on panel g2d.drawImage(dest,0,0,this); //writing new image to a file in jpeg format ImageIO.write(dest,"jpeg",new File("dest.jpg")); }catch(Exception e){ e.printStackTrace(); } } public BufferedImage changeBrightness(BufferedImage src,float val){ RescaleOp brighterOp = new RescaleOp(val, 0, null); return brighterOp.filter(src,null); //filtering } public static void main (String[] args) { JFrame jf=new JFrame("BRIGHTEN"); Brighten obj=new Brighten(); jf.getContentPane().add(obj); jf.setVisible(true); jf.setSize(325,270); jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE); } } 

希望有人能尽快帮助我..

这是一个基本的例子。

它使用一个特殊的ImagePanel来负责渲染图像。 它有自己的鼠标监听器来处理光标的更改和调整操作。

缩放算法基于分而治之的方法,以提供相当快速但高质量的规模。

我没有做对角resize,我会把它留给你;)

在此处输入图像描述

 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 (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException 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("C:\\hold\\thumbnails\\MT002.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(); px -= clickPoint.x; py -= clickPoint.y; p = SwingUtilities.convertPoint(ImagePane.this, p, getParent()); setLocation(p); } break; case ResizeWest: { Point p = e.getPoint(); int xDelta = px - 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 = px - clickPoint.x; int width = getWidth() + xDelta; setSize(width, getHeight()); revalidate(); clickPoint = p; } break; case ResizeNorth: { Point p = e.getPoint(); int yDelta = py - 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 = py - 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; } } 

最好将鼠标监听器作为视图面板的一部分而不是图像面板,这样你可以更好地重用这两个,但我会把它留给你

注意事项

重要的是要知道在处理null布局时,您要对容器内所有组件的大小和位置负责。 这增加了一些通常应该避免的工作量。

检查类似问题的答案: Scala Java Image

添加getScaledImage(...)方法,而不是:

 BufferedImage dest=changeBrightness(src,1.5f); 

添加这个:

 int width = this.getWidth(); int height = this.getHeight(); BufferedImage dest = getScaledImage(src, width, height); 

然后你会得到一个组件,其图像在每次重绘时都会缩放。