parent
834a68f372
commit
7ba094f077
@ -0,0 +1,164 @@ |
||||
package com.frank.ffmpeg.util; |
||||
|
||||
import android.graphics.Bitmap; |
||||
import android.graphics.BitmapFactory; |
||||
import android.graphics.ImageFormat; |
||||
import android.graphics.Matrix; |
||||
import android.graphics.Rect; |
||||
import android.graphics.YuvImage; |
||||
import android.util.Log; |
||||
|
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.IOException; |
||||
|
||||
public class ImageConverter { |
||||
|
||||
private byte[] yuv; |
||||
private int[] argb; |
||||
private Rect mRect; |
||||
private int[] pixels; |
||||
|
||||
private final Matrix mMatrix; |
||||
private ByteArrayOutputStream mOutputStream; |
||||
private final static boolean useSystem = false; |
||||
|
||||
public ImageConverter() { |
||||
mMatrix = new Matrix(); |
||||
} |
||||
|
||||
public Bitmap yuv2bitmap(byte[] data, int width, int height) { |
||||
if (useSystem) { |
||||
return yuv2bitmapSystem(data, width, height); |
||||
} else { |
||||
return yuvToBitmapFormula(data, width, height); |
||||
} |
||||
} |
||||
|
||||
private Bitmap yuv2bitmapSystem(byte[] data, int width, int height) { |
||||
Bitmap bmp = null; |
||||
try { |
||||
YuvImage image = new YuvImage(data, ImageFormat.NV21, width, height, null); |
||||
if (mRect == null) { |
||||
mRect = new Rect(0, 0, width, height); |
||||
} |
||||
if (mOutputStream == null) { |
||||
mOutputStream = new ByteArrayOutputStream(); |
||||
} else { |
||||
mOutputStream.reset(); |
||||
} |
||||
image.compressToJpeg(mRect, 100, mOutputStream); |
||||
bmp = BitmapFactory.decodeByteArray(mOutputStream.toByteArray(), 0, mOutputStream.size()); |
||||
} catch (Exception ex) { |
||||
Log.e("ImageConverter", "Error:" + ex.getMessage()); |
||||
} |
||||
return bmp; |
||||
} |
||||
|
||||
private int yuvToARGB(int y, int u, int v) { |
||||
int r, g, b; |
||||
|
||||
r = y + (int) (1.402f * u); |
||||
g = y - (int) (0.344f * v + 0.714f * u); |
||||
b = y + (int) (1.772f * v); |
||||
r = r > 255 ? 255 : Math.max(r, 0); |
||||
g = g > 255 ? 255 : Math.max(g, 0); |
||||
b = b > 255 ? 255 : Math.max(b, 0); |
||||
return 0xff000000 | (r << 16) | (g << 8) | b; |
||||
} |
||||
|
||||
private Bitmap yuvToBitmapFormula(byte[] data, int width, int height) { |
||||
if (pixels == null) { |
||||
pixels = new int[width * height]; |
||||
} |
||||
int size = width * height; |
||||
int offset = size; |
||||
int u, v, y1, y2, y3, y4; |
||||
|
||||
for (int i = 0, k = 0; i < size; i += 2, k += 2) { |
||||
y1 = data[i] & 0xff; |
||||
y2 = data[i + 1] & 0xff; |
||||
y3 = data[width + i] & 0xff; |
||||
y4 = data[width + i + 1] & 0xff; |
||||
|
||||
u = data[offset + k] & 0xff; |
||||
v = data[offset + k + 1] & 0xff; |
||||
u = u - 128; |
||||
v = v - 128; |
||||
|
||||
pixels[i] = yuvToARGB(y1, u, v); |
||||
pixels[i + 1] = yuvToARGB(y2, u, v); |
||||
pixels[width + i] = yuvToARGB(y3, u, v); |
||||
pixels[width + i + 1] = yuvToARGB(y4, u, v); |
||||
|
||||
if (i != 0 && (i + 2) % width == 0) |
||||
i += width; |
||||
} |
||||
return Bitmap.createBitmap(pixels, width, height, Bitmap.Config.ARGB_8888); |
||||
} |
||||
|
||||
public Bitmap rotateBitmap(Bitmap source, float angle) { |
||||
mMatrix.reset(); |
||||
mMatrix.postRotate(angle); |
||||
return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), |
||||
mMatrix, true); |
||||
} |
||||
|
||||
public Bitmap rotateAndFlipBitmap(Bitmap source, float angle, boolean xFlip, boolean yFlip) { |
||||
mMatrix.reset(); |
||||
mMatrix.postRotate(angle); |
||||
mMatrix.postScale(xFlip ? -1 : 1, yFlip ? -1 : 1, |
||||
source.getWidth() / 2f, source.getHeight() / 2f); |
||||
return Bitmap.createBitmap(source, 0, 0, |
||||
source.getWidth(), source.getHeight(), mMatrix, true); |
||||
} |
||||
|
||||
|
||||
public byte[] rgbaToYUV420p(Bitmap bitmap, int width, int height) { |
||||
final int frameSize = width * height; |
||||
int index = 0; |
||||
int yIndex = 0; |
||||
int uIndex = frameSize; |
||||
int vIndex = frameSize * 5 / 4; |
||||
int R, G, B, Y, U, V; |
||||
|
||||
if (argb == null) { |
||||
argb = new int[width * height]; |
||||
} |
||||
if (yuv == null) { |
||||
yuv = new byte[width * height * 3 / 2]; |
||||
} |
||||
bitmap.getPixels(argb, 0, width, 0, 0, width, height); |
||||
|
||||
for (int j = 0; j < height; j++) { |
||||
for (int i = 0; i < width; i++) { |
||||
R = (argb[index] & 0xff0000) >> 16; |
||||
G = (argb[index] & 0xff00) >> 8; |
||||
B = (argb[index] & 0xff); |
||||
|
||||
// RGB to YUV algorithm
|
||||
Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16; |
||||
|
||||
yuv[yIndex++] = (byte) Y; // -128~127
|
||||
if (j % 2 == 0 && i % 2 == 0) { |
||||
U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128; |
||||
V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128; |
||||
yuv[uIndex++] = (byte) U; |
||||
yuv[vIndex++] = (byte) V; |
||||
} |
||||
index++; |
||||
} |
||||
} |
||||
return yuv; |
||||
} |
||||
|
||||
public void close() { |
||||
if (mOutputStream != null) { |
||||
try { |
||||
mOutputStream.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue