近似色探索
近似色を探して似ている色であれば色を残して、似ていなければ色を白に設定しています。
閾値を低く設定すれば判定が厳しくなり、閾値を高く設定すれば判定が緩くなります。
private Bitmap searchApproximationColor( Bitmap bitmap, int approximationNumber, int YYY, int XXX ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); if( YYY < 0 ){ YYY = 0; } else if( width <= YYY ){ YYY = width -1; } if( XXX < 0 ){ XXX = 0; } else if( height <= XXX ){ XXX = height -1; } int targetBitmapColor = pixels[( YYY + XXX * width )]; for( int YY = 1; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( targetBitmapColor ) - Color.red( bitmapColor ); int gg = Color.green( targetBitmapColor ) - Color.green( bitmapColor ); int bb = Color.blue( targetBitmapColor ) - Color.blue( bitmapColor ); if( approximationNumber < Math.sqrt( rr * rr + gg * gg + bb * bb ) ){ pixels[( YY + XX * width )] = Color.rgb( 255, 255, 255 ); } } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; }
オリジナル:
近似色探索(真中・閾値30)(違いは詳細で見てください):
近似色探索(真中・閾値60)(違いは詳細で見てください):
近似色探索(真中・閾値90)(違いは詳細で見てください):
近似色探索(左下・閾値30)(違いは詳細で見てください):
近似色探索(左下・閾値60)(違いは詳細で見てください):
近似色探索(左下・閾値90)(違いは詳細で見てください):
近似色探索(右上・閾値30)(違いは詳細で見てください):
近似色探索(右上・閾値60)(違いは詳細で見てください):
近似色探索(右上・閾値90)(違いは詳細で見てください):
ちゃんとやるならタップした画像の座標をベースにして近似色を探します。。。これでネタ切れ。_| ̄|○
今までに紹介してきた処理はPhotoshopで簡単に処理できます。。。が、GIMPでも簡単に処理できるんだよね。
Photoshopを使ってみてツールの凄さを実感したのと同時にGIMPの凄さも実感しました。
エッジ検出(鮮鋭化)
基本的にエッジ検出(単体パターン)処理ですが、ぼやけていたような輪郭が強調されて鮮明になります。
検出された輪郭を分かりやすくする為に、事前にグレースケール処理を行ってから処理しています。
private Bitmap edgeDetectionSharpening( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int[] pixelsCopy = pixels.clone( ); int[][] pattern = { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } }; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int rr = 0; int gg = 0; int bb = 0; for( int Y = -1; Y <= 1; ++Y ){ for( int X = -1; X <= 1; ++X ){ if( ( Y + YY ) < 0 || width <= ( Y + YY ) || ( X + XX ) < 0 || height <= ( X + XX ) ){ continue; } int bitmapColor = pixels[( ( Y + YY ) + ( X + XX ) * width )]; rr += Color.red( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; gg += Color.green( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; bb += Color.blue( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; } } rr = Math.abs( rr ); gg = Math.abs( gg ); bb = Math.abs( bb ); if( rr > 255 ){ rr = 255; } if( gg > 255 ){ gg = 255; } if( bb > 255 ){ bb = 255; } pixelsCopy[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixelsCopy, 0, width, 0, 0, width, height ); return bitmap; }
エッジ検出(エンボス)
基本的にエッジ検出(単体パターン)処理ですが、RGB値を求めるときに、それぞれ128を足しています。
エンボスとは凸凹感を出して浮き彫りのような効果を出すことらしい。
検出された輪郭を分かりやすくする為に、事前にグレースケール処理を行ってから処理しています。
private Bitmap edgeDetectionEmbos( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int[] pixelsCopy = pixels.clone( ); int[][] pattern = { { 0, -1, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int rr = 0; int gg = 0; int bb = 0; for( int Y = -1; Y <= 1; ++Y ){ for( int X = -1; X <= 1; ++X ){ if( ( Y + YY ) < 0 || width <= ( Y + YY ) || ( X + XX ) < 0 || height <= ( X + XX ) ){ continue; } int bitmapColor = pixels[( ( Y + YY ) + ( X + XX ) * width )]; rr += Color.red( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; gg += Color.green( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; bb += Color.blue( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; } } rr = Math.abs( rr ) + 128; gg = Math.abs( gg ) + 128; bb = Math.abs( bb ) + 128; if( rr > 255 ){ rr = 255; } if( gg > 255 ){ gg = 255; } if( bb > 255 ){ bb = 255; } pixelsCopy[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixelsCopy, 0, width, 0, 0, width, height ); return bitmap; }
エッジ検出(複数パターン)
基本的にエッジ検出(単体パターン)処理ですが、パターンを複数適用しています。
これにより、より鮮明に輪郭部分を検出することができるらしい。
検出された輪郭を分かりやすくする為に、事前にグレースケール処理を行ってから処理しています。
private Bitmap edgeDetectionPatternMultiple( Bitmap bitmap, int patternFlg ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int[] pixelsCopy = pixels.clone( ); int[][] patternX; int[][] patternY; // Prewitt int[][] patternX1 = { { -1, -1, -1 }, { 0, 0, 0 }, { 1, 1, 1 } }; int[][] patternY1 = { { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 } }; // Sobel int[][] patternX2 = { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } }; int[][] patternY2 = { { -1, 0, 1 }, { -2, 0, 2 }, { -1, 0, 1 } }; // Roberts int[][] patternX3 = { { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, -1 } }; int[][] patternY3 = { { 0, 0, 0 }, { 0, 0, 1 }, { 0, -1, 0 } }; switch( patternFlg ){ case 2 : patternX = patternX2; patternY = patternY2; break; case 3 : patternX = patternX3; patternY = patternY3; break; default : patternX = patternX1; patternY = patternY1; break; } for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int rrX = 0; int ggX = 0; int bbX = 0; int rrY = 0; int ggY = 0; int bbY = 0; for( int Y = -1; Y <= 1; ++Y ){ for( int X = -1; X <= 1; ++X ){ if( ( Y + YY ) < 0 || width <= ( Y + YY ) || ( X + XX ) < 0 || height <= ( X + XX ) ){ continue; } int bitmapColor = pixels[( ( Y + YY ) + ( X + XX ) * width )]; rrX += Color.red( bitmapColor ) * patternX[( Y + 1 )][( X + 1 )]; ggX += Color.green( bitmapColor ) * patternX[( Y + 1 )][( X + 1 )]; bbX += Color.blue( bitmapColor ) * patternX[( Y + 1 )][( X + 1 )]; rrY += Color.red( bitmapColor ) * patternY[( Y + 1 )][( X + 1 )]; ggY += Color.green( bitmapColor ) * patternY[( Y + 1 )][( X + 1 )]; bbY += Color.blue( bitmapColor ) * patternY[( Y + 1 )][( X + 1 )]; } } int rr = (int)Math.sqrt( rrX * rrX + rrY * rrY ); int gg = (int)Math.sqrt( ggX * ggX + ggY * ggY ); int bb = (int)Math.sqrt( bbX * bbX + bbY * bbY ); if( rr > 255 ){ rr = 255; } if( gg > 255 ){ gg = 255; } if( bb > 255 ){ bb = 255; } pixelsCopy[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixelsCopy, 0, width, 0, 0, width, height ); return bitmap; }
オリジナル:
エッジ検出(複数パターン1)(違いは詳細で見てください):
エッジ検出(複数パターン2)(違いは詳細で見てください):
エッジ検出(複数パターン3)(違いは詳細で見てください):
エッジ検出(単体パターン)
エッジ。。。輪郭を検出する処理です。検出方向によって検出結果が変わるらしい。ここでは12パターンくらい用意して確認。
検出された輪郭を分かりやすくする為に、事前にグレースケール処理を行ってから処理しています。
private Bitmap edgeDetectionPattern( Bitmap bitmap, int patternFlg ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int[] pixelsCopy = pixels.clone( ); int[][] pattern; int[][] pattern01 = { { 0, -1, 0 }, { 0, 1, 0 }, { 0, 0, 0 } }; int[][] pattern02 = { { 0, -2, 0 }, { 0, 2, 0 }, { 0, 0, 0 } }; int[][] pattern03 = { { 0, 0, 0 }, { -1, 1, 0 }, { 0, 0, 0 } }; int[][] pattern04 = { { 0, 0, 0 }, { -2, 2, 0 }, { 0, 0, 0 } }; int[][] pattern05 = { { 0, -1, 0 }, { 0, 0, 0 }, { 0, 1, 0 } }; int[][] pattern06 = { { 0, 0, 0 }, { 1, 0, -1 }, { 0, 0, 0 } }; int[][] pattern07 = { { -1, -1, 0 }, { -1, 0, 1 }, { 0, 1, 1 } }; int[][] pattern08 = { { 0, -1, -1 }, { 1, 0, 1 }, { 1, 1, 0 } }; int[][] pattern09 = { { -1, 0, 1 }, { -1, 0, 1 }, { -1, 0, 1 } }; int[][] pattern10 = { { -1, -1, -1 }, { 0, 0, 0 }, { 1, 1, 1 } }; int[][] pattern11 = { { -1, -2, -1 }, { 0, 0, 0 }, { 1, 2, 1 } }; int[][] pattern12 = { { 1, 0, -1 }, { 2, 0, -2 }, { 1, 0, 1 } }; switch( patternFlg ){ case 2 : pattern = pattern02; break; case 3 : pattern = pattern03; break; case 4 : pattern = pattern04; break; case 5 : pattern = pattern05; break; case 6 : pattern = pattern06; break; case 7 : pattern = pattern07; break; case 8 : pattern = pattern08; break; case 9 : pattern = pattern09; break; case 10 : pattern = pattern10; break; case 11 : pattern = pattern11; break; case 12 : pattern = pattern12; break; default : pattern = pattern01; break; } for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int rr = 0; int gg = 0; int bb = 0; for( int Y = -1; Y <= 1; ++Y ){ for( int X = -1; X <= 1; ++X ){ if( ( Y + YY ) < 0 || width <= ( Y + YY ) || ( X + XX ) < 0 || height <= ( X + XX ) ){ continue; } int bitmapColor = pixels[( ( Y + YY ) + ( X + XX ) * width )]; rr += Color.red( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; gg += Color.green( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; bb += Color.blue( bitmapColor ) * pattern[( Y + 1 )][( X + 1 )]; } } rr = Math.abs( rr ); gg = Math.abs( gg ); bb = Math.abs( bb ); if( rr > 255 ){ rr = 255; } if( gg > 255 ){ gg = 255; } if( bb > 255 ){ bb = 255; } pixelsCopy[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixelsCopy, 0, width, 0, 0, width, height ); return bitmap; }
オリジナル:
エッジ検出(パターン1)(違いは詳細で見てください):
エッジ検出(パターン2)(違いは詳細で見てください):
エッジ検出(パターン3)(違いは詳細で見てください):
エッジ検出(パターン4)(違いは詳細で見てください):
エッジ検出(パターン5)(違いは詳細で見てください):
エッジ検出(パターン6)(違いは詳細で見てください):
エッジ検出(パターン7)(違いは詳細で見てください):
エッジ検出(パターン8)(違いは詳細で見てください):
エッジ検出(パターン9)(違いは詳細で見てください):
エッジ検出(パターン10)(違いは詳細で見てください):
エッジ検出(パターン11)(違いは詳細で見てください):
エッジ検出(パターン12)(違いは詳細で見てください):
ネタが少しだけ増えたので再開。。。すぐにネタ切れになりますけど。_| ̄|○
ブレンドモード
まとめて公開。。。これでネタ切れ。_| ̄|○
// ブレンドモード(加算) private Bitmap effectBlendAdd( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); rr = rr + mergeR; gg = gg + mergeG; bb = bb + mergeB; if( rr > 255 ){ rr = 255; } if( gg > 255 ){ gg = 255; } if( bb > 255 ){ bb = 255; } pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(乗算) private Bitmap effectBlendMultiple( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); rr = ( rr * mergeR ) / 255; gg = ( gg * mergeG ) / 255; bb = ( bb * mergeB ) / 255; pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(減算) private Bitmap effectBlendDifference( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); rr = rr - mergeR; gg = gg - mergeG; bb = bb - mergeB; if( rr < 0 ){ rr = 0; } if( gg < 0 ){ gg = 0; } if( bb < 0 ){ bb = 0; } pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(スクリーン) private Bitmap effectBlendScreen( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); rr = 255 - ( ( 255 - rr ) * ( 255 - mergeR ) ) / 255; gg = 255 - ( ( 255 - gg ) * ( 255 - mergeG ) ) / 255; bb = 255 - ( ( 255 - bb ) * ( 255 - mergeB ) ) / 255; pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(オーバーレイ) private Bitmap effectBlendOverlay( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); if( rr < 128 ){ rr = rr * mergeR * 2 / 255; } else { rr = 2 * ( rr + mergeR - rr * mergeR / 255 ) - 255; } if( gg < 128 ){ gg = gg * mergeG * 2 / 255; } else { gg = 2 * ( gg + mergeG - gg * mergeG / 255 ) - 255; } if( bb < 128 ){ bb = bb * mergeB * 2 / 255; } else { bb = 2 * ( bb + mergeB - bb * mergeB / 255 ) - 255; } if( rr > 255 ){ rr = 255; } if( gg > 255 ){ gg = 255; } if( bb > 255 ){ bb = 255; } pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(覆い焼き) private Bitmap effectBlendDodge( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); if( mergeR == 255 ){ rr = 255; } else { rr = rr * 255 / ( 255 - mergeR ); } if( mergeG == 255 ){ gg = 255; } else { gg = gg * 255 / ( 255 - mergeG ); } if( mergeB == 255 ){ bb = 255; } else { bb = bb * 255 / ( 255 - mergeB ); } if( rr > 255 ){ rr = 255; } if( gg > 255 ){ gg = 255; } if( bb > 255 ){ bb = 255; } pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(焼き込み) private Bitmap effectBlendBurn( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); if( mergeR == 0 ){ rr = 0; } else { rr = 255 - ( ( 255 - rr ) * 255 / mergeR ); } if( mergeG == 0 ){ gg = 0; } else { gg = 255 - ( ( 255 - gg ) * 255 / mergeG ); } if( mergeB == 0 ){ bb = 0; } else { bb = 255 - ( ( 255 - bb ) * 255 / mergeB ); } if( rr < 0 ){ rr = 0; } if( gg < 0 ){ gg = 0; } if( bb < 0 ){ bb = 0; } pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(比較・暗) private Bitmap effectBlendDarken( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); if( rr > mergeR ){ rr = mergeR; } if( gg > mergeG ){ gg = mergeG; } if( bb > mergeB ){ bb = mergeB; } pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(比較・明) private Bitmap effectBlendLighten( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); if( rr < mergeR ){ rr = mergeR; } if( gg < mergeG ){ gg = mergeG; } if( bb < mergeB ){ bb = mergeB; } pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; } // ブレンドモード(除外) private Bitmap effectBlendExclusion( Bitmap bitmap ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); int mergeR = 250, mergeG = 153, mergeB = 10; for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); rr = rr + mergeR - 2 * rr * mergeR / 255; gg = gg + mergeG - 2 * gg * mergeG / 255; bb = bb + mergeB - 2 * bb * mergeB / 255; pixels[( YY + XX * width )] = Color.rgb( rr, gg, bb ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); return bitmap; }
オリジナル:
ブレンドモード(加算)(違いは詳細で見てください):
ブレンドモード(乗算)(違いは詳細で見てください):
ブレンドモード(減算)(違いは詳細で見てください):
ブレンドモード(スクリーン)(違いは詳細で見てください):
ブレンドモード(オーバーレイ)(違いは詳細で見てください):
ブレンドモード(覆い焼き)(違いは詳細で見てください):
ブレンドモード(焼き込み)(違いは詳細で見てください):
ブレンドモード(比較・暗)(違いは詳細で見てください):
ブレンドモード(比較・明)(違いは詳細で見てください):
ブレンドモード(除外)(違いは詳細で見てください):
本来であれば二枚の画像を使って処理するのですが、面倒だったので二枚目の画像(RGB値)は固定にしています。手抜きでスミマセン。。。_| ̄|○
新しいネタが蓄積されてきたら再び公開するかもしれません。。。
ポラロイド
といっても単に画像を重ねたダケです。
// ポラロイド private Bitmap effectPolaroid( Bitmap bitmap, boolean flg ){ if( bitmap == null ){ bitmap = BitmapFactory.decodeResource( getResources( ), R.drawable.original ).copy( Bitmap.Config.ARGB_8888, true ); } if( bitmap == null ){ return bitmap; } if( bitmap.isMutable( ) != true ){ bitmap = bitmap.copy( Bitmap.Config.ARGB_8888, true ); } if( flg == true ){ int height = bitmap.getHeight( ); int width = bitmap.getWidth( ); int[] pixels = new int[( width * height )]; bitmap.getPixels( pixels, 0, width, 0, 0, width, height ); for( int YY = 0; YY < width; ++YY ){ for( int XX = 0; XX < height; ++XX ){ int bitmapColor = pixels[( YY + XX * width )]; int rr = Color.red( bitmapColor ); int gg = Color.green( bitmapColor ); int bb = Color.blue( bitmapColor ); // hsv[0] is Hue [0.0f .. 360.0f] // hsv[1] is Saturation [0.0f...1.0f] // hsv[2] is Value [0.0f...1.0.0f] float[] hsv = new float[3]; Color.RGBToHSV( rr, gg, bb, hsv ); hsv[1] *= 1.5f; hsv[2] -= 0.1f; if( 1 < hsv[1] ){ hsv[1] = 1.0f; } else if( hsv[1] < 0 ){ hsv[1] = 0.0f; } if( 1 < hsv[2] ){ hsv[2] = 1.0f; } else if ( hsv[2] < 0 ){ hsv[2] = 0.0f; } pixels[( YY + XX * width )] = Color.HSVToColor( hsv ); } } bitmap.setPixels( pixels, 0, width, 0, 0, width, height ); } bitmap = mergeBitmap( bitmap, BitmapFactory.decodeResource( getResources( ), R.drawable.polaroid ).copy( Bitmap.Config.ARGB_8888, true ) ); return bitmap; } // 画像を合成 private Bitmap mergeBitmap( Bitmap bitmap1, Bitmap bitmap2 ){ if( bitmap1 == null ){ return null; } if( bitmap2 == null ){ return bitmap1; } int height1 = bitmap1.getHeight( ); int width1 = bitmap1.getWidth( ); int height2 = bitmap2.getHeight( ); int width2 = bitmap2.getWidth( ); float scaleWidth = ( (float)width1 ) / width2; float scaleHeight = ( (float)height1 ) / height2; Matrix matrix = new Matrix( ); matrix.postScale( scaleWidth, scaleHeight ); Bitmap mergeBitmap = Bitmap.createBitmap( bitmap2, 0, 0, width2, height2, matrix, true ); Bitmap newBitmap = Bitmap.createBitmap( width1, height1, Bitmap.Config.ARGB_8888 ); Canvas canvas = new Canvas( newBitmap ); canvas.drawBitmap( bitmap1, 0.0f, 0.0f, null ); canvas.drawBitmap( mergeBitmap, 0.0f, 0.0f, null ); return newBitmap; }
オリジナル:
ポラロイド台紙(詳細で見てください):
ポラロイド(調整無)(違いは詳細で見てください):
ポラロイド(調整有)(違いは詳細で見てください):
単なる画像の合成なのに合成する画像の作成に時間がかかって疲れた。。。慣れない事はするもんじゃないね。_| ̄|○
Photoshopのスキルが少しだけ上がったから良しとしたい。。。