package jjil.android;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import jjil.core.RgbVal;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Environment;
public class DebugImage {
public static class Nv21Image {
public Nv21Image(byte[] data, int width, int height) {
this.mData = data;
this.mWidth = width;
this.mHeight = height;
}
public byte[] getData() {
return mData;
}
public int getHeight() {
return mHeight;
}
public int getWidth() {
return mWidth;
}
private byte[] mData;
private int mHeight, mWidth;
}
public static Nv21Image readGrayImage(String szFilename) {
Bitmap bmp = readBitmap(szFilename);
int width = bmp.getWidth();
int height = bmp.getHeight();
byte[] bResult = new byte[width * height];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
// turn the color image to gray
int pix = bmp.getPixel(j, i);
int r = (pix & 0x00ff0000) >> 16;
int g = (pix & 0x0000ff00) >> 8;
int b = (pix & 0x000000ff);
int gray = (r + g + b) / 3;
bResult[i * width + j] = RgbVal.unsignedIntToSignedByte[gray];
}
}
return new Nv21Image(bResult, width, height);
}
public static Nv21Image readImage2Nv21(String szFilename) {
Bitmap bmp = readBitmap(szFilename);
int width = bmp.getWidth();
int height = bmp.getHeight();
byte[] bResult = new byte[width * height + width * height / 2];
int nVuOffset = width * height;
// we compute the VU value on each 4 pixel block and the gray
// value on every pixel
for (int i = 0; i < height; i += 2) {
for (int j = 0; j < width; j += 2) {
int pix = bmp.getPixel(j, i);
int r = (pix & 0x00ff0000) >> 16;
int g = (pix & 0x0000ff00) >> 8;
int b = (pix & 0x000000ff);
int nSumR = r;
int nSumG = g;
int nSumB = b;
int nGray = (r + g + b) / 3;
bResult[i * width + j] = RgbVal.unsignedIntToSignedByte[nGray];
pix = bmp.getPixel(j + 1, i);
r = (pix & 0x00ff0000) >> 16;
g = (pix & 0x0000ff00) >> 8;
b = (pix & 0x000000ff);
nSumR += r;
nSumG += g;
nSumB += b;
nGray = (r + g + b) / 3;
bResult[i * width + j + 1] = RgbVal.unsignedIntToSignedByte[nGray];
pix = bmp.getPixel(j, i + 1);
r = (pix & 0x00ff0000) >> 16;
g = (pix & 0x0000ff00) >> 8;
b = (pix & 0x000000ff);
nSumR += r;
nSumG += g;
nSumB += b;
nGray = (r + g + b) / 3;
bResult[(i + 1) * width + j] = RgbVal.unsignedIntToSignedByte[nGray];
pix = bmp.getPixel(j + 1, i + 1);
r = (pix & 0x00ff0000) >> 16;
g = (pix & 0x0000ff00) >> 8;
b = (pix & 0x000000ff);
nSumR += r;
nSumG += g;
nSumB += b;
nGray = (r + g + b) / 3;
bResult[(i + 1) * width + j + 1] = RgbVal.unsignedIntToSignedByte[nGray];
// now compute the UV value for the 4-pixel block
int nYUV = AndroidColors.rgb2yuv(nSumR / 4, nSumG / 4,
nSumB / 4);
bResult[nVuOffset + i / 2 * width + j] = RgbVal.unsignedIntToSignedByte[nYUV & 0x000000ff];
bResult[nVuOffset + i / 2 * width + j + 1] = RgbVal.unsignedIntToSignedByte[(nYUV & 0x0000ff00) >> 8];
}
}
return new Nv21Image(bResult, width, height);
}
private static Bitmap readBitmap(String szFilename) {
File path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File file = new File(path, szFilename);
return BitmapFactory.decodeFile(file.getAbsolutePath());
}
private static boolean writeBitmap(String szFilename, Bitmap bmp) {
try {
File path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
path.mkdirs();
File file = new File(path, szFilename);
OutputStream os = new FileOutputStream(file);
if (szFilename.toLowerCase().endsWith(".jpg")) {
bmp.compress(CompressFormat.JPEG, 100, os);
} else {
bmp.compress(CompressFormat.PNG, 100, os);
}
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
return true;
}
public static boolean writeGrayImage(byte[] bImageData, int width,
int height, String szFilename) {
Bitmap bmp = Bitmap
.createBitmap(width, height, Bitmap.Config.ARGB_8888);
int[] nImageData = new int[width * height];
for (int i = 0; i < width * height; i++) {
int nValue = 0xff & bImageData[i];
nImageData[i] = Color.argb(0xff, nValue, nValue, nValue);
}
bmp.setPixels(nImageData, 0, width, 0, 0, width, height);
return writeBitmap(szFilename, bmp);
}
public static boolean writeNv21Image(byte[] bImageData, int width,
int height, String szFilename) {
Bitmap bmp = Bitmap
.createBitmap(width, height, Bitmap.Config.ARGB_8888);
int[] nImageData = new int[width * height];
int nVuOffset = width * height;
for (int i = 0; i < height; i++) {
// we produce two pixels for each VU pair in the color plane
for (int j = 0; j < width; j += 2) {
int nY = 0xff & bImageData[i * width + j];
int nV = 0xff & bImageData[nVuOffset + (i / 2) * width + j];
int nU = 0xff & bImageData[nVuOffset + (i / 2) * width + j + 1];
nImageData[i * width + j] = AndroidColors.yuv2Color(nY, nU, nV);
nY = 0xff & bImageData[i * width + j + 1];
nImageData[i * width + j + 1] = AndroidColors.yuv2Color(nY, nU,
nV);
}
}
bmp.setPixels(nImageData, 0, width, 0, 0, width, height);
return writeBitmap(szFilename, bmp);
}
}