M.U.G.E.Nは基本256色画像しか扱えない。その上で24bit画像を再現しようとすると結局のところRGBそれぞれ256階調の画像を用意してTrans=Addで重ねる方法が基本だと思う*1。
で、今まではGIMPを使って
- RGB分離
- グレースケール保存
- edgeでRGBそれぞれの階調のグラデーションパレットに変更
とかしてました。
でも画像がいっぱいあると凄まじく面倒なのですよ。ついでに最近は32bit画像 (つまりはアルファ) の再現も使用した結果、DirectXのテクスチャツールも併用するから面倒くささ倍増中だった *2。
いい加減楽したかったのでRGBAを分離してそれぞれ256階調のbmpにして吐き出すプログラムを書いた。以下がそのソース。
import java.awt.image.*; import java.io.*; import java.util.*; import java.util.concurrent.*; import javax.imageio.*; public class RGBSeparator implements Runnable { //----------------------------------------------------------------------------// // Fields --------------------------------------------------------------------// //----------------------------------------------------------------------------// private File output = null; private File source = null; //----------------------------------------------------------------------------// // Class Methods -------------------------------------------------------------// //----------------------------------------------------------------------------// public static void main(String[] args) throws Exception { BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(); ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 8, 30, TimeUnit.SECONDS, queue); for (String arg : args) { RGBSeparator sep = new RGBSeparator(arg); executor.execute(sep); } executor.shutdown(); executor.awaitTermination(30, TimeUnit.MINUTES); } private static synchronized boolean createDirectory(File dir) { if (!dir.exists()) { return dir.mkdirs(); } return true; } //----------------------------------------------------------------------------// // Constructors --------------------------------------------------------------// //----------------------------------------------------------------------------// public RGBSeparator(String file) { this(new File(file)); } public RGBSeparator(File file) { this(file, new File(System.getProperty("user.dir"))); } public RGBSeparator(File src, File dir) { super(); this.output = dir; this.source = src; } //----------------------------------------------------------------------------// // Methods -------------------------------------------------------------------// //----------------------------------------------------------------------------// public void run() { System.out.println(String.format("[Object#%x] Started at %d [ms]", this.hashCode(), System.currentTimeMillis())); try { this.resolve(); } catch (Exception ex) { throw new RuntimeException(ex.getMessage(), ex); } System.out.println(String.format("[Object#%x] Finished at %d [ms]", this.hashCode(), System.currentTimeMillis())); } public void resolve() throws IOException { BufferedImage image = ImageIO.read(this.source); //System.out.println(String.format("Image Type = %d", image.getType())); // 出力パレット byte[] palette = new byte[256]; for (int i = 0; i < 256; i++) { palette[i] = (byte) i; } byte[] emptyPalette = new byte[256]; for (int i = 0; i < 256; i++) { emptyPalette[i] = 0; } IndexColorModel red = new IndexColorModel(8, 256, palette, emptyPalette, emptyPalette); IndexColorModel green = new IndexColorModel(8, 256, emptyPalette, palette, emptyPalette); IndexColorModel blue = new IndexColorModel(8, 256, emptyPalette, emptyPalette, palette); // 出力画像を作成 BufferedImage redImg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_INDEXED, red); BufferedImage greenImg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_INDEXED, green); BufferedImage blueImg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_INDEXED, blue); BufferedImage alphaImg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_GRAY); // ピクセルを操作 int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); int[] pixels = new int[4]; Raster data = image.getRaster(); WritableRaster redData = redImg.getRaster(); WritableRaster greenData = greenImg.getRaster(); WritableRaster blueData = blueImg.getRaster(); WritableRaster alphaData = alphaImg.getRaster(); for (int x = 0; x < imageWidth; x++) { for (int y = 0; y < imageHeight; y++) { pixels = data.getPixel(x, y, pixels); //System.out.println(String.format("R=0x%02x,G=0x%02x,B=0x%02x", pixels[0], pixels[1], pixels[2])); // 書き込み redData.setPixel(x, y, new int[]{pixels[0]}); greenData.setPixel(x, y, new int[]{pixels[1]}); blueData.setPixel(x, y, new int[]{pixels[2]}); alphaData.setPixel(x, y, new int[]{pixels[3]}); } } // 書き込み File redDir = new File(this.output, "red"); File greenDir = new File(this.output, "green"); File blueDir = new File(this.output, "blue"); File alphaDir = new File(this.output, "alpha"); createDirectory(redDir); createDirectory(greenDir); createDirectory(blueDir); createDirectory(alphaDir); ImageIO.write(redImg, "bmp", new File(redDir, this.source.getName() + ".bmp")); ImageIO.write(greenImg, "bmp", new File(greenDir, this.source.getName() + ".bmp")); ImageIO.write(blueImg, "bmp", new File(blueDir, this.source.getName() + ".bmp")); ImageIO.write(alphaImg, "bmp", new File(alphaDir, this.source.getName() + ".bmp")); } }
コンパイルは各人でお願いします*3。