Created
December 29, 2014 10:23
-
-
Save easternHong/d5023ce9febb6badacce to your computer and use it in GitHub Desktop.
YUV420_to_RGB;decodeYUV420SPtoLuma;rgbToBitmap;lumaToGreyscale;
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package com.jwetherell.motion_detection.image; | |
| import java.io.ByteArrayOutputStream; | |
| import android.graphics.Bitmap; | |
| import android.graphics.BitmapFactory; | |
| import android.graphics.Color; | |
| import android.graphics.Matrix; | |
| /** | |
| * This abstract class is used to process images. | |
| * | |
| * @author Justin Wetherell <[email protected]> | |
| */ | |
| public abstract class ImageProcessing { | |
| public static final int A = 0; | |
| public static final int R = 1; | |
| public static final int G = 2; | |
| public static final int B = 3; | |
| public static final int H = 0; | |
| public static final int S = 1; | |
| public static final int L = 2; | |
| private ImageProcessing() { | |
| } | |
| /** | |
| * Get RGB values from pixel. | |
| * | |
| * @param pixel | |
| * Integer representation of a pixel. | |
| * @return float array of a,r,g,b values. | |
| */ | |
| public static float[] getARGB(int pixel) { | |
| int a = (pixel >> 24) & 0xff; | |
| int r = (pixel >> 16) & 0xff; | |
| int g = (pixel >> 8) & 0xff; | |
| int b = (pixel) & 0xff; | |
| return (new float[] { a, r, g, b }); | |
| } | |
| /** | |
| * Get HSL (Hue, Saturation, Luma) from RGB. Note1: H is 0-360 (degrees) | |
| * Note2: S and L are 0-100 (percent) | |
| * | |
| * @param r | |
| * Red value. | |
| * @param g | |
| * Green value. | |
| * @param b | |
| * Blue value. | |
| * @return Integer array representing an HSL pixel. | |
| */ | |
| public static int[] convertToHSL(int r, int g, int b) { | |
| float red = r / 255; | |
| float green = g / 255; | |
| float blue = b / 255; | |
| float minComponent = Math.min(red, Math.min(green, blue)); | |
| float maxComponent = Math.max(red, Math.max(green, blue)); | |
| float range = maxComponent - minComponent; | |
| float h = 0, s = 0, l = 0; | |
| l = (maxComponent + minComponent) / 2; | |
| if (range == 0) { // Monochrome image | |
| h = s = 0; | |
| } else { | |
| s = (l > 0.5) ? range / (2 - range) : range / (maxComponent + minComponent); | |
| if (red == maxComponent) { | |
| h = (blue - green) / range; | |
| } else if (green == maxComponent) { | |
| h = 2 + (blue - red) / range; | |
| } else if (blue == maxComponent) { | |
| h = 4 + (red - green) / range; | |
| } | |
| } | |
| // convert to 0-360 (degrees) | |
| h *= 60; | |
| if (h < 0) h += 360; | |
| // convert to 0-100 (percent) | |
| s *= 100; | |
| l *= 100; | |
| // Since they were converted from float to int | |
| return (new int[] { (int) h, (int) s, (int) l }); | |
| } | |
| /** | |
| * Decode a YUV420SP image to Luma. | |
| * | |
| * @param yuv420sp | |
| * Byte array representing a YUV420SP image. | |
| * @param width | |
| * Width of the image. | |
| * @param height | |
| * Height of the image. | |
| * @return Integer array representing the Luma image. | |
| * @throws NullPointerException | |
| * if yuv420sp byte array is NULL. | |
| */ | |
| public static int[] decodeYUV420SPtoLuma(byte[] yuv420sp, int width, int height) { | |
| if (yuv420sp == null) throw new NullPointerException(); | |
| final int frameSize = width * height; | |
| int[] hsl = new int[frameSize]; | |
| for (int j = 0, yp = 0; j < height; j++) { | |
| for (int i = 0; i < width; i++, yp++) { | |
| int y = (0xff & (yuv420sp[yp])) - 16; | |
| if (y < 0) y = 0; | |
| hsl[yp] = y; | |
| } | |
| } | |
| return hsl; | |
| } | |
| /** | |
| * Decode a YUV420SP image to RGB. | |
| * | |
| * @param yuv420sp | |
| * Byte array representing a YUV420SP image. | |
| * @param width | |
| * Width of the image. | |
| * @param height | |
| * Height of the image. | |
| * @return Integer array representing the RGB image. | |
| * @throws NullPointerException | |
| * if yuv420sp byte array is NULL. | |
| */ | |
| public static int[] decodeYUV420SPtoRGB(byte[] yuv420sp, int width, int height) { | |
| if (yuv420sp == null) throw new NullPointerException(); | |
| final int frameSize = width * height; | |
| int[] rgb = new int[frameSize]; | |
| for (int j = 0, yp = 0; j < height; j++) { | |
| int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; | |
| for (int i = 0; i < width; i++, yp++) { | |
| int y = (0xff & (yuv420sp[yp])) - 16; | |
| if (y < 0) y = 0; | |
| if ((i & 1) == 0) { | |
| v = (0xff & yuv420sp[uvp++]) - 128; | |
| u = (0xff & yuv420sp[uvp++]) - 128; | |
| } | |
| int y1192 = 1192 * y; | |
| int r = (y1192 + 1634 * v); | |
| int g = (y1192 - 833 * v - 400 * u); | |
| int b = (y1192 + 2066 * u); | |
| if (r < 0) r = 0; | |
| else if (r > 262143) r = 262143; | |
| if (g < 0) g = 0; | |
| else if (g > 262143) g = 262143; | |
| if (b < 0) b = 0; | |
| else if (b > 262143) b = 262143; | |
| rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); | |
| } | |
| } | |
| return rgb; | |
| } | |
| /** | |
| * Convert an RGB image into a Bitmap. | |
| * | |
| * @param rgb | |
| * Integer array representing an RGB image. | |
| * @param width | |
| * Width of the image. | |
| * @param height | |
| * Height of the image. | |
| * @return Bitmap of the RGB image. | |
| * @throws NullPointerException | |
| * if RGB integer array is NULL. | |
| */ | |
| public static Bitmap rgbToBitmap(int[] rgb, int width, int height) { | |
| if (rgb == null) throw new NullPointerException(); | |
| Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); | |
| bitmap.setPixels(rgb, 0, width, 0, 0, width, height); | |
| return bitmap; | |
| } | |
| /** | |
| * Convert an Luma image into Greyscale. | |
| * | |
| * @param lum | |
| * Integer array representing an Luma image. | |
| * @param width | |
| * Width of the image. | |
| * @param height | |
| * Height of the image. | |
| * @return Bitmap of the Luma image. | |
| * @throws NullPointerException | |
| * if RGB integer array is NULL. | |
| */ | |
| public static Bitmap lumaToGreyscale(int[] lum, int width, int height) { | |
| if (lum == null) throw new NullPointerException(); | |
| Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565); | |
| for (int y = 0, xy = 0; y < bitmap.getHeight(); y++) { | |
| for (int x = 0; x < bitmap.getWidth(); x++, xy++) { | |
| int luma = lum[xy]; | |
| bitmap.setPixel(x, y, Color.argb(1, luma, luma, luma)); | |
| } | |
| } | |
| return bitmap; | |
| } | |
| /** | |
| * Rotate the given Bitmap by the given degrees. | |
| * | |
| * @param bmp | |
| * Bitmap to rotate. | |
| * @param degrees | |
| * Degrees to rotate. | |
| * @return Bitmap which was rotated. | |
| */ | |
| public static Bitmap rotate(Bitmap bmp, int degrees) { | |
| if (bmp == null) throw new NullPointerException(); | |
| // getting scales of the image | |
| int width = bmp.getWidth(); | |
| int height = bmp.getHeight(); | |
| // Creating a Matrix and rotating it to 90 degrees | |
| Matrix matrix = new Matrix(); | |
| matrix.postRotate(degrees); | |
| // Getting the rotated Bitmap | |
| Bitmap rotatedBmp = Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, true); | |
| ByteArrayOutputStream stream = new ByteArrayOutputStream(); | |
| rotatedBmp.compress(Bitmap.CompressFormat.JPEG, 100, stream); | |
| return rotatedBmp; | |
| } | |
| /** | |
| * Rotate the given image in byte array format by the given degrees. | |
| * | |
| * @param data | |
| * Bitmap to rotate in byte array form. | |
| * @param degrees | |
| * Degrees to rotate. | |
| * @return Byte array format of an image which was rotated. | |
| */ | |
| public static byte[] rotate(byte[] data, int degrees) { | |
| if (data == null) throw new NullPointerException(); | |
| // Convert the byte data into a Bitmap | |
| Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length); | |
| // Getting the rotated Bitmap | |
| Bitmap rotatedBmp = rotate(bmp, degrees); | |
| // Get the byte array from the Bitmap | |
| ByteArrayOutputStream stream = new ByteArrayOutputStream(); | |
| rotatedBmp.compress(Bitmap.CompressFormat.JPEG, 100, stream); | |
| return stream.toByteArray(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment