gpt4 book ai didi

java - 如何使图像在 Swing 时可拉伸(stretch)?

转载 作者:行者123 更新时间:2023-12-01 18:45:12 26 4
gpt4 key购买 nike

目前我正在通过 BufferedImage 在 Jframe swing 组件中加载图像。图像加载成功,但我希望当用户选择图像的右下角并尝试调整其大小时使图像可拉伸(stretch),然后它就成为可能。用户可以保存调整大小的图像,但如何做到这一点我不知道确切的想法。因此,如果有人指导我,我将非常感激。我不需要完整的代码,但我只想要指导和提示。

我的代码如下:

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来负责渲染图像。它有自己的鼠标监听器来处理光标的更改和调整大小操作。

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

我还没有完成对角线大小的调整,我会把它留给你;)

enter image description here

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();
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;
}
}

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

注意事项

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

关于java - 如何使图像在 Swing 时可拉伸(stretch)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18053310/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com