/*这个问题困惑了很久,问我们java老师也能没解决,真诚地希望您能帮我解答一下,thanks for your time and consideration!问题描述:从文件里读取一个图像--->使图像旋转一个角度--->保存旋转后的图像(.jpg)(宽和高也相应的变化。前两步已实现,就是保存旋转后的图像出问题,宽和高是可以实现变换的,但保存的图像始终没有旋转,但可以看到图像在panel里是显现出来已经转了啊?不明白,那些旋转数据缓存到哪里了?为了明白起见,我把每次点击鼠标后图像的变化都有保存,你要找个(* * .jpg)的图像,修改程序中两处文件路径,程序可以运行。
*/
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
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.JScrollPane;public class ScrollPaneDemo extends JFrame implements MouseListener { private static final long serialVersionUID = -8833161611850547265L; ImagePanel jp; JScrollPane jsp;
public ScrollPaneDemo() {
super("JScrollPane Demo 图像旋转");
jp = new ImagePanel();
jp.setPreferredSize(new Dimension(800, 600));
jsp = new JScrollPane(jp);
jp.addMouseListener(this);
getContentPane().add(jsp);
setSize(1000,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new ScrollPaneDemo();
} public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked");
//jp.enlarge();
jp.RotateRight();
jp.setPreferredSize(jp.getPreferredSize());
jsp.validate();
} public void mousePressed(MouseEvent e) {
// System.out.println("mousePressed");
} public void mouseReleased(MouseEvent e) {
// System.out.println("mouseReleased");
} public void mouseEntered(MouseEvent e) {
// System.out.println("mouseEntered");
} public void mouseExited(MouseEvent e) {
// System.out.println("mouseExited");
}
}class ImagePanel extends JPanel { private Image image; //要旋转的图像
private double currentAngle;//当前角度 private Dimension theSize = new Dimension(800,600); double w = theSize.getWidth(); double h = theSize.getHeight(); public ImagePanel() {
this.image = Toolkit.getDefaultToolkit().getImage("F:\\vvECC\\Winter.jpg"); //从文件中读取图像
MediaTracker mt = new MediaTracker(this);
mt.addImage(image, 0);
try {
mt.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public void paintComponent(Graphics g) {
System.out.println("in paintComponent");
File newImage;
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
AffineTransform origXform = g2d.getTransform();
AffineTransform newXform = (AffineTransform) (origXform.clone());
int xRot = this.getWidth() / 2;
int yRot = this.getHeight() / 2;
newXform.rotate(Math.toRadians(currentAngle), xRot, yRot);
g2d.setTransform(newXform);
int x = (getWidth() - image.getWidth(this)) / 2;
int y = (getHeight() - image.getHeight(this)) / 2;
g2d.drawImage(image, x, y, this);
/*
* g2d.drawImage(image, x, y, this),我理解为把旋转后的出来,此时"image"已被旋转了吗?
* 可用下面的几行代码的保存的大小变化正确,但图像本身始终是没有旋转的。不明白.
*/ BufferedImage bImage = new BufferedImage(theSize.width, theSize.height, BufferedImage.TYPE_INT_RGB);
Graphics gr = bImage.getGraphics();
gr.dispose();
newImage = new File("F:/vvECC/NewImage.jpg");
try {
ImageIO.write(bImage, "jpg", newImage);//把bImage写到newImage.jpg
} catch (IOException e) {
e.printStackTrace();
}
g2d.setTransform(origXform);
} public void RotateRight() {
currentAngle +=30.0;// 顺时针旋转30度
// currentAngle -= 30.0;//逆时针旋转30度
if (currentAngle >= 360.0) {
currentAngle = 0;
} double cos = Math.abs(Math.cos(Math.toRadians(currentAngle)));
double sin = Math.abs(Math.sin(Math.toRadians(currentAngle))); theSize.width = (int) (w * cos + h * sin);
theSize.height = (int) (w * sin + h * cos); setSize(theSize); repaint();
} public Dimension getPreferredSize() {
return this.theSize;
}
}
*/
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
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.JScrollPane;public class ScrollPaneDemo extends JFrame implements MouseListener { private static final long serialVersionUID = -8833161611850547265L; ImagePanel jp; JScrollPane jsp;
public ScrollPaneDemo() {
super("JScrollPane Demo 图像旋转");
jp = new ImagePanel();
jp.setPreferredSize(new Dimension(800, 600));
jsp = new JScrollPane(jp);
jp.addMouseListener(this);
getContentPane().add(jsp);
setSize(1000,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new ScrollPaneDemo();
} public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked");
//jp.enlarge();
jp.RotateRight();
jp.setPreferredSize(jp.getPreferredSize());
jsp.validate();
} public void mousePressed(MouseEvent e) {
// System.out.println("mousePressed");
} public void mouseReleased(MouseEvent e) {
// System.out.println("mouseReleased");
} public void mouseEntered(MouseEvent e) {
// System.out.println("mouseEntered");
} public void mouseExited(MouseEvent e) {
// System.out.println("mouseExited");
}
}class ImagePanel extends JPanel { private Image image; //要旋转的图像
private double currentAngle;//当前角度 private Dimension theSize = new Dimension(800,600); double w = theSize.getWidth(); double h = theSize.getHeight(); public ImagePanel() {
this.image = Toolkit.getDefaultToolkit().getImage("F:\\vvECC\\Winter.jpg"); //从文件中读取图像
MediaTracker mt = new MediaTracker(this);
mt.addImage(image, 0);
try {
mt.waitForID(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
} public void paintComponent(Graphics g) {
System.out.println("in paintComponent");
File newImage;
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
AffineTransform origXform = g2d.getTransform();
AffineTransform newXform = (AffineTransform) (origXform.clone());
int xRot = this.getWidth() / 2;
int yRot = this.getHeight() / 2;
newXform.rotate(Math.toRadians(currentAngle), xRot, yRot);
g2d.setTransform(newXform);
int x = (getWidth() - image.getWidth(this)) / 2;
int y = (getHeight() - image.getHeight(this)) / 2;
g2d.drawImage(image, x, y, this);
/*
* g2d.drawImage(image, x, y, this),我理解为把旋转后的出来,此时"image"已被旋转了吗?
* 可用下面的几行代码的保存的大小变化正确,但图像本身始终是没有旋转的。不明白.
*/ BufferedImage bImage = new BufferedImage(theSize.width, theSize.height, BufferedImage.TYPE_INT_RGB);
Graphics gr = bImage.getGraphics();
gr.dispose();
newImage = new File("F:/vvECC/NewImage.jpg");
try {
ImageIO.write(bImage, "jpg", newImage);//把bImage写到newImage.jpg
} catch (IOException e) {
e.printStackTrace();
}
g2d.setTransform(origXform);
} public void RotateRight() {
currentAngle +=30.0;// 顺时针旋转30度
// currentAngle -= 30.0;//逆时针旋转30度
if (currentAngle >= 360.0) {
currentAngle = 0;
} double cos = Math.abs(Math.cos(Math.toRadians(currentAngle)));
double sin = Math.abs(Math.sin(Math.toRadians(currentAngle))); theSize.width = (int) (w * cos + h * sin);
theSize.height = (int) (w * sin + h * cos); setSize(theSize); repaint();
} public Dimension getPreferredSize() {
return this.theSize;
}
}
extends Object
implements ImageConsumerThe PixelGrabber class implements an ImageConsumer which can be attached to an Image or ImageProducer object to retrieve a subset of the pixels in that image. Here is an example: public void handlesinglepixel(int x, int y, int pixel) {
int alpha = (pixel >> 24) & 0xff;
int red = (pixel >> 16) & 0xff;
int green = (pixel >> 8) & 0xff;
int blue = (pixel ) & 0xff;
// Deal with the pixel as necessary...
} public void handlepixels(Image img, int x, int y, int w, int h) {
int[] pixels = new int[w * h];
PixelGrabber pg = new PixelGrabber(img, x, y, w, h, pixels, 0, w);
try {
pg.grabPixels();
} catch (InterruptedException e) {
System.err.println("interrupted waiting for pixels!");
return;
}
if ((pg.getStatus() & ImageObserver.ABORT) != 0) {
System.err.println("image fetch aborted or errored");
return;
}
for (int j = 0; j < h; j++) {
for (int i = 0; i < w; i++) {
handlesinglepixel(x+i, y+j, pixels[j * w + i]);
}
}
} public class MemoryImageSource
extends Object
implements ImageProducerThis class is an implementation of the ImageProducer interface which uses an array to produce pixel values for an Image. Here is an example which calculates a 100x100 image representing a fade from black to blue along the X axis and a fade from black to red along the Y axis:
int w = 100;
int h = 100;
int pix[] = new int[w * h];
int index = 0;
for (int y = 0; y < h; y++) {
int red = (y * 255) / (h - 1);
for (int x = 0; x < w; x++) {
int blue = (x * 255) / (w - 1);
pix[index++] = (255 << 24) | (red << 16) | blue;
}
}
Image img = createImage(new MemoryImageSource(w, h, pix, 0, w));
The MemoryImageSource is also capable of managing a memory image which varies over time to allow animation or custom rendering. Here is an example showing how to set up the animation source and signal changes in the data (adapted from the MemoryAnimationSourceDemo by Garth Dickie): int pixels[];
MemoryImageSource source; public void init() {
int width = 50;
int height = 50;
int size = width * height;
pixels = new int[size]; int value = getBackground().getRGB();
for (int i = 0; i < size; i++) {
pixels[i] = value;
} source = new MemoryImageSource(width, height, pixels, 0, width);
source.setAnimated(true);
image = createImage(source);
} public void run() {
Thread me = Thread.currentThread( );
me.setPriority(Thread.MIN_PRIORITY); while (true) {
try {
thread.sleep(10);
} catch( InterruptedException e ) {
return;
} // Modify the values in the pixels array at (x, y, w, h) // Send the new data to the interested ImageConsumers
source.newPixels(x, y, w, h);
}
}
至于你们老师解决不了这个问题, 并不是说明这个问题难.再指出一点, 把
try {
ImageIO.write(bImage, "jpg", newImage);//把bImage写到newImage.jpg
} catch (IOException e) {
e.printStackTrace();
}
放在paintComponent中, 实在是一大败笔.
因为paintComponent这个函数很可能会执行很多次, 难道你每次都想把图片写到同一个文件中?