package util; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; public class ImageTransform { /** * @param bitmap * the source * @param factor * should be between 2f (very visible round corners) and 20f * (nearly no round corners) * @return the result */ public static Bitmap createBitmapWithRoundCorners(Bitmap bitmap, float factor) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); Bitmap result = Bitmap.createBitmap(width, height, bitmap.getConfig()); Canvas canvas = new Canvas(result); Rect rect = new Rect(0, 0, width, height); RectF roundCornerFrameRect = new RectF(rect); float cornerRadius = width / factor; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); canvas.drawRoundRect(roundCornerFrameRect, cornerRadius, cornerRadius, paint); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return result; } /** * This will scale the image first to add soft corners * * @param bitmap * @param angle * @param smoothingFactor * try 1.5f; (1 would be no smoothing at all) * @return */ public static Bitmap rotateBitmap(Bitmap bitmap, int angle, float smoothingFactor) { Bitmap result = ImageTransform.resizeBitmap(bitmap, bitmap.getHeight() * smoothingFactor, bitmap.getWidth() * smoothingFactor); result = rotateBitmap(result, angle); result = ImageTransform.resizeBitmap(result, result.getHeight() / smoothingFactor, result.getWidth() / smoothingFactor); return result; } public static Bitmap rotateBitmap(Bitmap bitmap, int angle) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); Bitmap result = Bitmap.createBitmap(width, height, bitmap.getConfig()); Canvas canvas = new Canvas(result); Matrix matrix = new Matrix(); matrix.setRotate(angle, width / 2, height / 2); Paint p = new Paint(); p.setAntiAlias(true); canvas.drawBitmap(bitmap, matrix, p); return result; } public static Bitmap resizeBitmap(Bitmap bitmap, float newHeight, float newWidth) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); float scaleWidth = ((float) newWidth) / width; float scaleHeight = ((float) newHeight) / height; Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); } /** * From * http://android-developers.blogspot.com/2012/01/levels-in-renderscript * .html * * TODO add description for parameters * * @param sourceBitmap * @param resultBitmap * @param filterKernel * has to be a 3x3 matrix so float[9]. The kernal which will keep * all color values like they are is filterKernel={1,0,0, 0,1,0, * 0,0,1}. * @param mOverInWMinInB * from 0 to 1 * @param gammaValue * from 0 to 1 * @param mOutWMinOutB * from 0 to 1 * @param mInBlack * from 0 to 255 * @param mOutBlack * from 0 to 255 */ public static void improveSaturation(Bitmap sourceBitmap, Bitmap resultBitmap, float[] filterKernel, float mOverInWMinInB, float gammaValue, float mOutWMinOutB, float mInBlack, float mOutBlack) { int[] mInPixels = new int[sourceBitmap.getHeight() * sourceBitmap.getWidth()]; int[] mOutPixels = new int[resultBitmap.getHeight() * resultBitmap.getWidth()]; sourceBitmap.getPixels(mInPixels, 0, sourceBitmap.getWidth(), 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight()); for (int i = 0; i < mInPixels.length; i++) { float r = (float) (mInPixels[i] & 0xff); float g = (float) ((mInPixels[i] >> 8) & 0xff); float b = (float) ((mInPixels[i] >> 16) & 0xff); float tr = r * filterKernel[0] + g * filterKernel[3] + b * filterKernel[6]; float tg = r * filterKernel[1] + g * filterKernel[4] + b * filterKernel[7]; float tb = r * filterKernel[2] + g * filterKernel[5] + b * filterKernel[8]; r = tr; g = tg; b = tb; if (r < 0.f) r = 0.f; if (r > 255.f) r = 255.f; if (g < 0.f) g = 0.f; if (g > 255.f) g = 255.f; if (b < 0.f) b = 0.f; if (b > 255.f) b = 255.f; r = (r - mInBlack) * mOverInWMinInB; g = (g - mInBlack) * mOverInWMinInB; b = (b - mInBlack) * mOverInWMinInB; if (gammaValue != 1.0f) { r = (float) java.lang.Math.pow(r, gammaValue); g = (float) java.lang.Math.pow(g, gammaValue); b = (float) java.lang.Math.pow(b, gammaValue); } r = (r * mOutWMinOutB) + mOutBlack; g = (g * mOutWMinOutB) + mOutBlack; b = (b * mOutWMinOutB) + mOutBlack; if (r < 0.f) r = 0.f; if (r > 255.f) r = 255.f; if (g < 0.f) g = 0.f; if (g > 255.f) g = 255.f; if (b < 0.f) b = 0.f; if (b > 255.f) b = 255.f; mOutPixels[i] = ((int) r) + (((int) g) << 8) + (((int) b) << 16) + (mInPixels[i] & 0xff000000); } resultBitmap.setPixels(mOutPixels, 0, resultBitmap.getWidth(), 0, 0, resultBitmap.getWidth(), resultBitmap.getHeight()); } /** * @param targetBitmap * @param type * 1 is Green-Blue, 2 is Red-Blue, 3 is Red - Green */ public static void switchColors(Bitmap targetBitmap, int type) { int width = targetBitmap.getWidth(); int height = targetBitmap.getHeight(); int[] srcPixels = new int[width * height]; targetBitmap.getPixels(srcPixels, 0, width, 0, 0, width, height); int[] destPixels = new int[width * height]; switch (type) { case 1: swapGreenBlue(srcPixels, destPixels); break; case 2: swapRedBlue(srcPixels, destPixels); break; case 3: swapRedGreen(srcPixels, destPixels); break; } targetBitmap.setPixels(destPixels, 0, width, 0, 0, width, height); } private static void swapGreenBlue(int[] src, int[] dest) { for (int i = 0; i < src.length; i++) { dest[i] = (src[i] & 0xffff0000) | ((src[i] & 0x000000ff) << 8) | ((src[i] & 0x0000ff00) >> 8); } } private static void swapRedBlue(int[] src, int[] dest) { for (int i = 0; i < src.length; i++) { dest[i] = (src[i] & 0xff00ff00) | ((src[i] & 0x000000ff) << 16) | ((src[i] & 0x00ff0000) >> 16); } } private static void swapRedGreen(int[] src, int[] dest) { for (int i = 0; i < src.length; i++) { dest[i] = (src[i] & 0xff0000ff) | ((src[i] & 0x0000ff00) << 8) | ((src[i] & 0x00ff0000) >> 8); } } }