- PR -

画像の回転

1
投稿者投稿内容
ゴールデン
常連さん
会議室デビュー日: 2004/08/22
投稿数: 46
投稿日時: 2004-08-22 11:41
java appletで画像を回転させるようプログラムしました。75×140の画像の(43,0)を中心として平面状で回転させるものです。元の画像を、1ピクセルず、中心点の周りを回転させ、それを300×300のサイズのピクセルに移して描画すればできると思って、次のような式を作り、描画してみました。回転はちゃんとできたのですが、描画する角度によって、空白のピクセルができてしまって、ところどころに小さなピクセルの穴が空いてしまうのです。拡大するのならピクセルに穴が空くわけも分かるのですが、拡大するわけでもないのに…というのは何かの計算からくる数値がそうさせていると思うのです。
それを解消したいのですが、どうしたらよいのでしょうか。教えていただきたいです。

rは回転角度です。
XとYは、元の画像サイズ。1ピクセルずつを取り出して、回転させようとしています。
4行目の”Math.round”を”(int)”に変えると穴がいっぱいになったので、”Math.round”に変えたら、回転角(r=0)の時はまったく穴ができませんでした。

for( Y=0; Y<140; Y++ ){
 for(X=0; X<75; X++ ){
  double hannkei=Math.sqrt(Math.pow(X-43,2)+Math.pow(Y,2));
  tx=Math.round(hannkei*Math.sin(Math.atan2(X-43,Y)+Math.toRadians(r)));
  ty=Math.round(hannkei*Math.cos(Math.atan2(X-43,Y)+Math.toRadians(r)));
  pixels[(int)((ty+150)*300+tx+150)]=org[Y*tw+X];
 }
}
mis.newPixels();
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2004-08-22 12:03
ゴールデンさん、こんにちは。

変換元のピクセルから変換先のピクセルを求めているために
整数への切捨てでそうなったのでしょう。

逆に、変換先のピクセルに対応する変換もとのピクセルを求め
る様にしたら隙間は空かなくなると思います。

あと、java.awt.geom.AffineTransformを使用するというのは
どうでしょう?
ゴールデン
常連さん
会議室デビュー日: 2004/08/22
投稿数: 46
投稿日時: 2004-08-22 14:15
>あと、java.awt.geom.AffineTransformを使用するというのは
>どうでしょう?
Kissingerさん、ありがとうございます。
java.awt.geom.AffineTransformというものをどのように使ったらよいのかが、リファレンスを見てもよくわかりませんでした。すみなせんが、もう少し詳しく教えていただけないでしょうか?AffineTransformの中の何をどのように使ったらよいかまで教いただけたら嬉しいです。
Kissinger
ぬし
会議室デビュー日: 2002/04/30
投稿数: 428
お住まい・勤務地: 愛知県
投稿日時: 2004-08-22 23:57
java.awt.Component#paint(Graphics g)や
javax.swing.JComponent#paintComponent(Graphics g)内で
java.awt.Graphics2D#drawImage(java.awt.geom.AffineTransform)を
使用します。

例です。
コード:
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;

public class DrawImage extends Component {
	private Image image;
	private AffineTransform xform;

	public static void main(String[] args) {
		DrawImage component = new DrawImage("dukeWave.gif");
		JFrame frame = new JFrame("draw image");
		frame.getContentPane().add(component);
		frame.setBounds(100, 100, 100, 100);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
	}

	public DrawImage(String fileName) {
		Toolkit toolkit = Toolkit.getDefaultToolkit();
		image = toolkit.getImage(fileName);

		double theta = Math.toRadians(45.0);
		xform = new AffineTransform();
		xform.rotate(theta, 43, 0);
	}

	public void paint(Graphics g) {
		super.paint(g);

		Graphics2D g2d = (Graphics2D)g;
		g2d.drawImage(image, xform, this);
	}
}



AffineTransformには rotate() のほかにも便利なメソッドが
ありますが、行列を使った方がより抽象的で柔軟な画像操作
ができます。
ゴールデン
常連さん
会議室デビュー日: 2004/08/22
投稿数: 46
投稿日時: 2004-08-23 16:34
ありがとうございました。Graphics2Dは今まで一回も使ったことはありませんでしたので、未知の世界でしたが、例を出してくださったので、それをもとにしてコードを書きました。振り子のように揺れる画像が作りたかったのです。無事できて、とても勉強になりました。今後ともよろしくお願いします。
1

スキルアップ/キャリアアップ(JOB@IT)