【Java】画像を連続で繋げるロジック(トランプをひっくり返すアニメーションなどに利用

6月 9, 2020

どうも、RPGツクールMVのプラグインを作る上で、
どうしても素材でトランプ画像を縦にくっつける必要がありました。

一つずつ手で繋げるのも面倒だったので、プログラムに全て任せてみました。

経緯

先日RPGツクールMVに向けたプラグインを作りました。
以下の記事で紹介しています。

プラグインを作るときに、どうしてもトランプの素材が必要でした。
さらにいうと、ロジックの関係上一枚一枚、ひっくり返るような素材が必要でした。


こういう感じですね。
一枚一枚トランプのひっくり返る画像を作ったのはいいのですが、
手で画像を繋げるのはかなり辛いと思いました。

Macのフリーウェアを探してみた


一枚一枚やっていくのであれば、このフリーウェアでもできそうでした。
これがあれば縦か横で画像を連続で繋げることができます。

一枚一枚やるのがとても手間

トランプの枚数は全52枚(ジョーカーを除く)
それを一つ一つやっていくのはとても手間でした。
一度に52枚分のカードを処理できないかなぁって思いました。

なければ作ればいいじゃない

ということで作ってみました。
一枚一枚手でやるのも面倒なので、
プログラムに全て任せるということになりました。

Javaで画像結合プログラムを作ってみた

環境

Javaバージョン:jdk1.8

前提

以下のような画像を用意します。

【裏面の画像】
ura1.png

ura2.png

ura3.png

ura4.png

【おもて面の画像】
s01.png(以降:Aタイプと呼ぶ)

s01.png(別ファイルとして用意する。以降:Bタイプと呼ぶ)

s01.png(更に別ファイルとして用意する。以降:Cタイプと呼ぶ)

各種トランプのファイル名について

ハートの1〜13:h01.png〜h13.png
スペードの1〜13:s01.png〜s13.png
クローバーの1〜13:c01.png〜c13.png
ダイヤの1〜13:d01.png〜d13.png

上記のハート〜ダイヤのトランプのカードを「Aタイプ」〜「Cタイプ」の形の画像をそれぞれ用意する。

フォルダ構成

プログラムのホームディレクトリに以下のフォルダを用意する。
フォルダ名:card1〜card3
card1には「Aタイプのカード」を全て格納
card2には「Bタイプのカード」を全て格納
card3には「Cタイプのカード」を全て格納

プログラムコード


import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

public class Combin {
	
	public static void main(String args[]) {
		
		try {
			List marks = new ArrayList();
			
			marks.add("c");
			marks.add("d");
			marks.add("h");
			marks.add("s");
			
			for (int i = 0 ; i < marks.size() ; i++) {
				for (int j = 1 ; j <=13 ; j++) {
					// 画像を読み込んでオブジェクトにする
					StringBuilder path1 = new StringBuilder();
					StringBuilder path2 = new StringBuilder();
					StringBuilder path3 = new StringBuilder();
					StringBuilder path4 = new StringBuilder();
					path1.append("cards/card1/");
					path2.append("cards/card2/");
					path3.append("cards/card3/");
					path4.append("cards/card4/");
					String cardNum = marks.get(i) + String.format("%02d", j);
					BufferedImage parts1 = ImageIO.read(new FileInputStream(path1.append(cardNum).append(".png").toString()));
					BufferedImage parts2 = ImageIO.read(new FileInputStream(path2.append(cardNum).append(".png").toString()));
					BufferedImage parts3 = ImageIO.read(new FileInputStream(path3.append(cardNum).append(".png").toString()));
					
					BufferedImage uraparts1 = ImageIO.read(new FileInputStream("cards/ura1.png"));
					BufferedImage uraparts2 = ImageIO.read(new FileInputStream("cards/ura2.png"));
					BufferedImage uraparts3 = ImageIO.read(new FileInputStream("cards/ura3.png"));
					BufferedImage uraparts4 = ImageIO.read(new FileInputStream("cards/ura4.png"));
					
					// 合成後の画像の縦横サイズを指定して、新しい画像オブジェクトを作る
					// 縦に並べるわけだから、縦幅は parts.png の2倍とっておく
					// この時点では画像は真っ黒な状態
					BufferedImage img = new BufferedImage(parts1.getWidth(), parts1.getHeight() * 7, BufferedImage.TYPE_INT_ARGB);
					// その真っ黒画像に描画するためのGraphicsオブジェクトを取り出して、
					// そこに parts.png を2度描く。Y座標は縦に並ぶようにずらす。
					Graphics g = img.getGraphics();
					g.drawImage(uraparts1, 0, 0, null);
					g.drawImage(uraparts2, 0, parts1.getHeight(), null);
					g.drawImage(uraparts3, 0, parts1.getHeight()*2, null);
					g.drawImage(uraparts4, 0, parts1.getHeight()*3, null);
					g.drawImage(parts1, 0, parts1.getHeight()*4, null);
					g.drawImage(parts2, 0, parts1.getHeight()*5, null);
					g.drawImage(parts3, 0, parts1.getHeight()*6, null);

					// 合成後の画像をファイルに出力
					ImageIO.write(img, "png", new File("kansei/"+cardNum+".png"));
				}
			}

		} catch(Exception e) {
			e.printStackTrace();
		}

	}

}

出力先

「kansei/」フォルダに出力されます。

結果


52枚分のひっくり返るアニメーション用の画像が出来上がります。

まとめ

目的のことをするだけなので、こんな作り方になりました。
便利にするにはもう少し改造が必要ですが、まずは簡単にこんな形で良いかなと思いました。

今回は以上!

スポンサーリンク