はじめに
以下の画像はなんのキャラクターのデフォルメでしょうか。
どことなく、国民的アニメの主人公に色合いが似てる気がしませんか?
モザイクをかけても人間はアニメキャラクターを見破ってしまう というのが先日話題になったので、同じように、Javaを利用して画像を配列と見た時に各行の平均の色を出力することで簡易モザイクを作成する流れを記事にしました。
Javaを利用したモザイク生成
Javaでの画像情報の取得は以下のように行います。
File f = new File("[入力画像のフルパス]"); BufferedImage read=ImageIO.read(f); int w = read.getWidth(); int h = read.getHeight();
BurreredImageのメソッドを用い、read.getにて縦横のサイズが取得可能できます。
こちらの情報は画像を配列として捌く際に使えます。
ここからモザイクを作成するために各画素を取り出す必要がありますが、BufferedImageでは画素を取得するメソッドgetRGBが用意されています。
こちらを用いると、 RGBに対応する情報が8bitずつで表現された値を取得できます。
00000000 00000000 00000000 00000000
この値からそれぞれの色データ R G B を取り出すために
public class Img{ public static int r(int c){ return c>>16&0xff; } public static int g(int c){ return c>>8&0xff; } public static int b(int c){ return c&0xff; } public static int rgb(int r,int g,int b){ return 0xff000000 | r <<16 | g <<8 | b; } }
といったクラスを自前で用意しました。
public static int rgb(int r,int g,int b)
にて各r,g,bを基に新たな画素情報を返り値として返すメソッドです。
画像の各列の画素の平均値の画像を出力するコードは以下になります。
public class Main { public static void main(String[] args) throws IOException { File f = new File("[入力画像のフルパス]"); BufferedImage read=ImageIO.read(f); int w = read.getWidth(); int h = read.getHeight(); BufferedImage write = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); for(int y=0;y<h;y++){ int r = 0; int g = 0; int b = 0; for(int x=0;x<w;x++){ int c = read.getRGB(x,y); r = r + Img.r(c); g = g + Img.g(c); b = b + Img.b(c); } int n_r = r/h; int n_g = g/h; int n_b = b/h; for(int xx=0;xx<w;xx++){ int rgb = Img.rgb(n_r, n_g, n_b); write.setRGB(xx, y, rgb); } } File f2 = new File("[出力先のフルパス]"); ImageIO.write(write, "jpg", f2); //jpgで出力 } }
このコードにて画像をモザイク化させて出力できます。
終わりに
ちなみに最初に見せたモザイク画像の元画像はこちらです。
出力されたモザイク画像は両端が黒くなってしまっています。これは、透明化している部分の画素が 0/0/0 として値が格納されていることが原因なのでこのあたりは改良の余地があります。
以上、ご参考になれば幸いです。