00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00026 package edu.uoc.ocr;
00027
00028 import android.graphics.Bitmap;
00029
00037 public final class PlanarYUVLuminanceSource extends LuminanceSource {
00038
00039 private final byte[] yuvData;
00040 private final int dataWidth;
00041 private final int dataHeight;
00042 private final int left;
00043 private final int top;
00044
00045 public PlanarYUVLuminanceSource(byte[] yuvData, int dataWidth,
00046 int dataHeight, int left, int top, int width, int height,
00047 boolean reverseHorizontal) {
00048 super(width, height);
00049
00050 if (left + width > dataWidth || top + height > dataHeight) {
00051 throw new IllegalArgumentException(
00052 "Crop rectangle does not fit within image data.");
00053 }
00054
00055 this.yuvData = yuvData;
00056 this.dataWidth = dataWidth;
00057 this.dataHeight = dataHeight;
00058 this.left = left;
00059 this.top = top;
00060 if (reverseHorizontal) {
00061 reverseHorizontal(width, height);
00062 }
00063 }
00064
00065 @Override
00066 public byte[] getRow(int y, byte[] row) {
00067 if (y < 0 || y >= getHeight()) {
00068 throw new IllegalArgumentException(
00069 "Requested row is outside the image: " + y);
00070 }
00071 int width = getWidth();
00072 if (row == null || row.length < width) {
00073 row = new byte[width];
00074 }
00075 int offset = (y + top) * dataWidth + left;
00076 System.arraycopy(yuvData, offset, row, 0, width);
00077 return row;
00078 }
00079
00080 @Override
00081 public byte[] getMatrix() {
00082 int width = getWidth();
00083 int height = getHeight();
00084
00085
00086
00087
00088
00089 if (width == dataWidth && height == dataHeight) {
00090 return yuvData;
00091 }
00092
00093 int area = width * height;
00094 byte[] matrix = new byte[area];
00095 int inputOffset = top * dataWidth + left;
00096
00097
00098
00099 if (width == dataWidth) {
00100 System.arraycopy(yuvData, inputOffset, matrix, 0, area);
00101 return matrix;
00102 }
00103
00104
00105 byte[] yuv = yuvData;
00106 for (int y = 0; y < height; y++) {
00107 int outputOffset = y * width;
00108 System.arraycopy(yuv, inputOffset, matrix, outputOffset, width);
00109 inputOffset += dataWidth;
00110 }
00111 return matrix;
00112 }
00113
00114 @Override
00115 public boolean isCropSupported() {
00116 return true;
00117 }
00118
00119 @Override
00120 public LuminanceSource crop(int left, int top, int width, int height) {
00121 return new PlanarYUVLuminanceSource(yuvData, dataWidth, dataHeight,
00122 this.left + left, this.top + top, width, height, false);
00123 }
00124
00125 public Bitmap renderCroppedGreyscaleBitmap() {
00126 int width = getWidth();
00127 int height = getHeight();
00128 int[] pixels = new int[width * height];
00129 byte[] yuv = yuvData;
00130 int inputOffset = top * dataWidth + left;
00131
00132 for (int y = 0; y < height; y++) {
00133 int outputOffset = y * width;
00134 for (int x = 0; x < width; x++) {
00135 int grey = yuv[inputOffset + x] & 0xff;
00136 pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
00137 }
00138 inputOffset += dataWidth;
00139 }
00140
00141 Bitmap bitmap = Bitmap.createBitmap(width, height,
00142 Bitmap.Config.ARGB_8888);
00143 bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
00144 return bitmap;
00145 }
00146
00147 private void reverseHorizontal(int width, int height) {
00148 byte[] yuvData = this.yuvData;
00149 for (int y = 0, rowStart = top * dataWidth + left; y < height; y++, rowStart += dataWidth) {
00150 int middle = rowStart + width / 2;
00151 for (int x1 = rowStart, x2 = rowStart + width - 1; x1 < middle; x1++, x2--) {
00152 byte temp = yuvData[x1];
00153 yuvData[x1] = yuvData[x2];
00154 yuvData[x2] = temp;
00155 }
00156 }
00157 }
00158
00159 }