using bitmap, camera capture but occur nullpointerException on android - java

I try camera preview capture on android.
use Bitmap.
but occur NullpointerException
java.lang.NullPointerException
at kr.co.mytest.test.video.CameraTextureView.getImage(CameraTextureView.java:167)
at kr.co.mytest.test.video.CameraTextureView.onPreviewFrame(CameraTextureView.java:161)
at android.hardware.Camera$EventHandler.handleMessage(Camera.java:936)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5001)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
CameraTextureView.class
public class CameraTextureView extends TextureView implements TextureView.SurfaceTextureListener, Camera.PreviewCallback {
private Camera mCamera;
private CaptureViewer captureView;
.
.
.
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d(TAG,"CHECK");
YuvImage image = new YuvImage(data, 20, 640 ,480, null);
Rect rect = new Rect(0, 0, 640, 480);
ByteArrayOutputStream bao = new ByteArrayOutputStream();
image.compressToJpeg(rect, 100, bao);
byte[] jpeg = bao.toByteArrary();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap convertedImage = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.length, options);
Log.d(TAG, "convertedImage" + convertedImage); //android.graphics.Bitmap#21ac0b78
getImage(Bitmap.createScaleBitmap(convertedImage, 480, 360, true)); //nullPointerException
}
public void getImage(Bitmap bitmap) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
captureView.displayImage(bitmap);
}
CaptureView.class
public class CaptureView extends View {
private Bitmap mBitmap = null;
public void displayImage(Bitmap image) {
mBitmap = Bitmap.createBitmap(image);
postInvalidate();
}
}
displayImage is only showing capture image.
why occur nullpointerException?
onPreviewFrameis Called as preview frames are displayed.
how to process occur nullPointerException?
thanks.!

Related

Adding image in ARCore database at runtime error

I want to add image at runtime in ARCore database. So, in my MainActivity.java, I have a button Registered Image, which on Click , added the image in ARCore database.
MainActivity.java :
public class MainActivity extends AppCompatActivity {
private CustomArFragment arFragment;
private TextView textView;
private AugmentedImageDatabase aid;
private Frame frame;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
arFragment = (CustomArFragment) getSupportFragmentManager().findFragmentById(R.id.arFragment);
textView = findViewById(R.id.textView);
arFragment.getArSceneView().getScene().addOnUpdateListener(this::onUpdate);
findViewById(R.id.registeredBtn).setOnClickListener(v -> {
if(ActivityCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
return;
}
registeredImage();
});
}
private static byte[] NV21toJPEG(byte[] nv21, int width, int height) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
YuvImage yuv = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
yuv.compressToJpeg(new Rect(0, 0, width, height), 100, out);
return out.toByteArray();
}
private static byte[] YUV_420_888toNV21(Image image) {
byte[] nv21;
ByteBuffer yBuffer = image.getPlanes()[0].getBuffer();
ByteBuffer uBuffer = image.getPlanes()[1].getBuffer();
ByteBuffer vBuffer = image.getPlanes()[2].getBuffer();
int ySize = yBuffer.remaining();
int uSize = uBuffer.remaining();
int vSize = vBuffer.remaining();
nv21 = new byte[ySize + uSize + vSize];
//U and V are swapped
yBuffer.get(nv21, 0, ySize);
vBuffer.get(nv21, ySize, vSize);
uBuffer.get(nv21, ySize + vSize, uSize);
return nv21;
}
// This function triggered when Registered image button clicked
private void registeredImage() {
File file = new File(getExternalFilesDir(null) + "/db.imgdb");
Frame CurrFrame = frame;
Image currentImage;
int idx = -1;
try {
currentImage = CurrFrame.acquireCameraImage();
byte[] data = null;
data = NV21toJPEG(YUV_420_888toNV21(currentImage),
currentImage.getWidth(), currentImage.getHeight());
FileOutputStream outputStream = new FileOutputStream(file);
Bitmap bitmap = BitmapFactory.decodeByteArray(data,0,data.length);
idx = aid.addImage("earth",bitmap);
aid.serialize(outputStream);
outputStream.close();
Toast.makeText(this, "image Registered", Toast.LENGTH_SHORT).show();
} catch (NotYetAvailableException | IOException e) {
e.printStackTrace();
}
}
private void onUpdate(FrameTime frameTime) {
frame = arFragment.getArSceneView().getArFrame();
Collection<AugmentedImage> images = frame.getUpdatedTrackables(AugmentedImage.class);
for(AugmentedImage image : images){
if(image.getTrackingMethod() == AugmentedImage.TrackingMethod.FULL_TRACKING){
if(image.getName().equals("test")){
textView.setText("Test is visible");
}
else if(image.getName().equals("earth")){
textView.setText("earth is visible");
}
}
}
}
}
When I clicked on button, the app crashes and image didnot add in database. Following are the errors when idx = aid.addImage("earth",bitmap); line called in registeredImage() function.
2020-10-05 14:11:39.738 31013-31013/com.example.artag E/native: error_policy_util.cc:261
################ ARCore Native Error ##################
BUILD_CHANGELIST:331869482
BUILD_BASELINE_CHANGELIST:331085015
################### Stack Trace Begin ################
ARCoreError: third_party/arcore/ar/planar_targets/augmented_image_database_utils.cc:58 https://cs.corp.google.com/piper///depot/google3/third_party/arcore/ar/planar_targets/augmented_image_database_utils.cc?g=0&l=58
ARCoreError: third_party/arcore/ar/core/c_api/augmented_image_database_c_api.cc:133 https://cs.corp.google.com/piper///depot/google3/third_party/arcore/ar/core/c_api/augmented_image_database_c_api.cc?g=0&l=133
################### Stack Trace End #################
2020-10-05 14:11:39.739 31013-31013/com.example.artag D/AndroidRuntime: Shutting down VM
2020-10-05 14:11:39.742 31013-31013/com.example.artag E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.artag, PID: 31013
com.google.ar.core.exceptions.ImageInsufficientQualityException
at java.lang.reflect.Constructor.newInstance0(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:343)
at com.google.ar.core.Session.throwExceptionFromArStatus(Session.java:101)
at com.google.ar.core.AugmentedImageDatabase.nativeAddImage(Native Method)
at com.google.ar.core.AugmentedImageDatabase.addImage(AugmentedImageDatabase.java:5)
at com.example.artag.MainActivity.registeredImage(MainActivity.java:130)
at com.example.artag.MainActivity.lambda$onCreate$0$MainActivity(MainActivity.java:72)
at com.example.artag.-$$Lambda$MainActivity$5zEkixen6UibjSKLs5AkDUICWdM.onClick(Unknown Source:2)
at android.view.View.performClick(View.java:7333)
at android.widget.TextView.performClick(TextView.java:14160)
at android.view.View.performClickInternal(View.java:7299)
at android.view.View.access$3200(View.java:846)
at android.view.View$PerformClick.run(View.java:27773)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6990)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
Please help to find out the problem,
Thanks :)
The image that you attempted to add to the database does not have enough features.
Check https://developers.google.com/ar/reference/java/com/google/ar/core/exceptions/ImageInsufficientQualityException#ImageInsufficientQualityException()
for the complete specification of the errors.
If you want users to upload images, I recommend using a try-catch-block and letting the user know about the error instead of having the app crash.

OutOfMemoryError exception when try to blur images

I'm trying blur some images 1024x1024 and sometimes I'm getting java.lang.OutOfMemoryError and i don't know why.
I'm testing directly in my tablet Android 4.1.2 and I have always 1.5gb Ram free.
Here the class I'm using:
package com.example.playerclient.blur;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.v8.renderscript.*;
public class BlurBuilder {
private static final float BITMAP_SCALE = 0.6f;
public static Bitmap blur(Context context, Bitmap image, float blurRadius) {
Bitmap outputBitmap = null;
if (image != null) {
if (blurRadius == 0) {
return image;
}
if (blurRadius < 1) {
blurRadius = 1;
}
if (blurRadius > 25) {
blurRadius = 25;
}
int width = Math.round(image.getWidth() * BITMAP_SCALE);
int height = Math.round(image.getHeight() * BITMAP_SCALE);
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
outputBitmap = Bitmap.createBitmap(inputBitmap);
RenderScript rs = RenderScript.create(context);
ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
theIntrinsic.setRadius(blurRadius);
theIntrinsic.setInput(tmpIn);
theIntrinsic.forEach(tmpOut);
tmpOut.copyTo(outputBitmap);
}
return outputBitmap;
}
}
Here where I call the method:
public class MusicaActivity extends AppCompatActivity implements View.OnClickListener {
// Others methods here.
private void mostraDadosMusica() {
Intent intent = getIntent();
Musica musica = (Musica)intent.getSerializableExtra(MainActivity.VISUALIZA_PLAYER);
// Where i'm having problems.
Bitmap originalBmp = BitmapFactory.decodeResource(getResources(), musica.getAlbum().getIdCapa());
Bitmap resultBmp = BlurBuilder.blur(this, originalBmp, 15f);
backgroundImageView.setImageBitmap(resultBmp);
}
}
Ande here the exception message:
11-04 22:05:07.453 18928-18928/com.example.playerclient E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:636)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:484)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:512)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:542)
at com.example.playerclient.activity.MusicaActivity.mostraDadosMusica(MusicaActivity.java:48)
at com.example.playerclient.activity.MusicaActivity.onCreate(MusicaActivity.java:87)
at android.app.Activity.performCreate(Activity.java:5188)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2074)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2135)
at android.app.ActivityThread.access$700(ActivityThread.java:140)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1237)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4921)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
at dalvik.system.NativeStart.main(Native Method)

Can't convert the relative layout with all the content to an image

I have the Relative Layout which has a scroll view and has more than 20 textviews.
when i try to convert this layout into a bitmap it is not happening
when i view it in an external storage it says "this file is damaged"
in gallery the image shows a black view
this is the code which i have used to convert the view to bitmap
public static Bitmap loadBitmapFromView(Context context, View v) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
v.measure(View.MeasureSpec.makeMeasureSpec(dm.widthPixels, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(dm.heightPixels, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
v.draw(c);
return bitmap;
}
I have passed the object of relative layout to loadBitmapFromView.
and
I have used this code for saving image to external storage
private void SaveImage(Bitmap finalBitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 100000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG,1000,out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
this is my logcat
12-30 15:02:20.397 24825-24825/com.google.android.gms.samples.vision.barcodereader W/System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
12-30 15:02:20.397 24825-24825/com.google.android.gms.samples.vision.barcodereader W/System.err: at com.google.android.gms.samples.vision.barcodereader.ResultActivity.SaveImage(ResultActivity.java:3483)
12-30 15:02:20.397 24825-24825/com.google.android.gms.samples.vision.barcodereader W/System.err: at com.google.android.gms.samples.vision.barcodereader.ResultActivity.onCreate(ResultActivity.java:137)
Your createBitmap function would be returning null, You try to obtain the bitmap like below.
final View v = mView.findViewById(R.id.your_view_id);
Bitmap b = Bitmap.createBitmap( v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
v.draw(c);
return b;
Try this
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(
v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}
and use it as
Bitmap b = loadBitmapFromView(your_layout_object);

Taking a picture and using the image - Out of memory error

OK, I am developing an android application that takes a photo using the camera, then uses that image in an ImageView.
The problem that I'm having is that I keep getting an java.lang.OutOfMemoryError exception when I try and load the image.
Code to start camera intent:
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
AlertDialog.Builder builder = new AlertDialog.Builder(AddVehicleActivity.this);
builder.setTitle("Select A Method");
builder.setItems(R.array.array_PhotoMethods, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch(which) {
case 0 :
IMAGE_LOCATION = Utility.setFileName(_session); //Returns image path
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(IMAGE_LOCATION)));
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
break;
}
}
});
builder.show();
}
});
From my understanding, this will allow the image to be saved at the full resolution of the camera which I can confirm through the image details in the gallery. Using my Samsung SIII, my image is about 3.3MB. So, I am able to use the camera and store the image I take using the camera to path I specify. The problem comes when trying to use the image.
To load the image, I use the following:
public static Bitmap Shrink(String file, int width, int height) {
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)height);
int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)width);
if (heightRatio > 1 || widthRatio > 1) {
bmpFactoryOptions.inSampleSize = (heightRatio > widthRatio) ? heightRatio : widthRatio;
}
return BitmapFactory.decodeFile(file, bmpFactoryOptions);
}
I have rewritten this functions a few different ways and found out that sometimes, I get the memory error when calling BitmapFactory.decodeFile
My stack trace looks like this:
E/dalvikvm-heap(8355): Out of memory on a 31961104-byte allocation.
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:619)
at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:385)
at com.autopilot.com.objects.Images.Shrink(Images.java:191)
at com.autopilot.com.adapters.ImageAdapter.getView(ImageAdapter.java:90)
at android.widget.AbsListView.obtainView(AbsListView.java:2437)
at android.widget.GridView.onMeasure(GridView.java:1030)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1396)
at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1038)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:576)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1396)
at android.widget.LinearLayout.measureHorizontal(LinearLayout.java:1038)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:576)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.LinearLayout.forceUniformWidth(LinearLayout.java:926)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:906)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15395)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:617)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:399)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:15395)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:833)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
at android.view.View.measure(View.java:15395)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4826)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2362)
at android.view.View.measure(View.java:15395)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1985)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1226)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1399)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4553)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
at android.view.Choreographer.doCallbacks(Choreographer.java:555)
at android.view.Choreographer.doFrame(Choreographer.java:525)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4950)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1004)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:771)
at dalvik.system.NativeStart.main(Native Method)
From tracing this through, the memory exception occurs anytime that the original bitmap is loaded. I cannot find a way to set the saved image size and when I try to save the bitmap from the intent extras, it's never big enough, usually thumb nail size.
Any help would be greatly appreciated!
OK, I found the answer, thank you sunil!
public static Bitmap Shrink(String file, int width, int height) {
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, options);
options.inSampleSize = calcSize(options, width, height);
options.inJustDecodeBounds = false;
Bitmap bmp = BitmapFactory.decodeFile(file, options);
return bmp;
}
public static int calcSize(BitmapFactory.Options options, int width, int height) {
final int uHeight = options.outHeight;
final int uWidth = options.outWidth;
int inSampleSize = 1;
if (uHeight > height || uWidth > width) {
if (uWidth > uHeight) {
inSampleSize = Math.round((float) uHeight / (float) height);
} else {
inSampleSize = Math.round((float) uWidth / (float) width);
}
}
return inSampleSize;
}

Tesseract RECOGNITION fix?

I have been able to export my code into an application and use the Tess-Two file from this tutorial
to integrate the tesseract into it. But now I'm facing problems; when the picture is sent to the tesseract it just returns the same random characters each time: 'f' wig, W fin. A. " 5' ' ,{ >>zv' ' ~" > ';>'. What seems to be the problem?
ImageView iv;
TextView tv;
protected Bitmap _image;
protected Bitmap bmp;
public static String The_path = "/mnt/sdcard/DCIM/100MEDIA/TESS.jpg";
public static String lang = "eng";
public static final String DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/SimpleAndroidOCR/";
private int pageSegmentationMode = TessBaseAPI.PageSegMode.PSM_AUTO;
#Override
public void onCreate(Bundle savedInstanceState) {
try {
AssetManager assetManager = getAssets();
InputStream in = assetManager.open("tessdata/eng.traineddata");
//GZIPInputStream gin = new GZIPInputStream(in);
OutputStream out = new FileOutputStream(DATA_PATH + "tessdata/eng.traineddata");
//Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
//while ((len = gin.read(buf)) > 0) {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
//gin.close();
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
iv = (ImageView) findViewById(R.id.imageView1);
tv = (TextView) findViewById(R.id.textView1);
Button but = (Button) findViewById(R.id.button1);
Button but2 = (Button) findViewById(R.id.button2);
but.setOnClickListener(new OnClickListener() {
public void onClick(View v){
//File file = new File( _path );
//Uri outputFileUri = Uri.fromFile( file );
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
//intent.putExtra( MediaStore.EXTRA_OUTPUT, outputFileUri );
startActivityForResult(intent, 0);
}
});
but2.setOnClickListener(new OnClickListener() {
public void onClick(View v){
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.setPageSegMode(pageSegmentationMode);
baseApi.init(DATA_PATH, lang);
// DATA_PATH = Path to the storage
// lang for which the language data exists, usually "eng"
try {
baseApi.setImage(ReadFile.readBitmap(bmp));
String recognizedText = baseApi.getUTF8Text();
txt(recognizedText);
} catch(RuntimeException e) {
}
baseApi.end();
}
private void txt(String txt) {
// TODO Auto-generated method stub
tv.setText(txt);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inSampleSize = 4;
Bitmap bitmap = BitmapFactory.decodeFile(The_path, options);
try {
ExifInterface exif = new ExifInterface(The_path);
int exifOrientation = exif.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
int rotate = 0;
switch (exifOrientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
}
if (rotate != 0) {
// Getting width & height of the given image.
int w = bitmap.getWidth();
int h = bitmap.getHeight();
// Setting pre rotate
Matrix mtx = new Matrix();
mtx.preRotate(rotate);
// Rotating Bitmap
bitmap = Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, false);
}
bitmap = toGrayscale(bitmap);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
} catch (IOException e) {
}
_image = (Bitmap) data.getExtras().get("data");
iv.setImageBitmap(_image);
bmp = bitmap;
} public static Bitmap toGrayscale(Bitmap bmpOriginal){
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}
here is the new log cat after adding the grayscale function:
(receiving a new set of reoccurring random characters)
01-26 10:21:36.973: D/libEGL(1389): loaded /system/lib/egl/libEGL_adreno200.so
01-26 10:21:36.973: D/libEGL(1389): loaded /system/lib/egl/libGLESv1_CM_adreno200.so
01-26 10:21:36.973: D/libEGL(1389): loaded /system/lib/egl/libGLESv2_adreno200.so
01-26 10:21:36.983: I/Adreno200-EGL(1389): <eglInitialize:269>: EGL 1.4 QUALCOMM build: Nondeterministic AU_full_mako_PARTNER-ANDROID/JB-MR1- DEV_CL2946718_release_AU (CL2946718)
01-26 10:21:36.983: I/Adreno200-EGL(1389): Build Date: 11/04/12 Sun
01-26 10:21:36.983: I/Adreno200-EGL(1389): Local Branch:
01-26 10:21:36.983: I/Adreno200-EGL(1389): Remote Branch: m/partner-android/jb-mr1-dev
01-26 10:21:36.983: I/Adreno200-EGL(1389): Local Patches: NONE
01-26 10:21:36.983: I/Adreno200-EGL(1389): Reconstruct Branch: NOTHING
01-26 10:21:37.043: D/OpenGLRenderer(1389): Enabling debug mode 0
01-26 10:21:45.502: E/BitmapFactory(1389): Unable to decode stream: java.io.FileNotFoundException: /mnt/sdcard/DCIM/100MEDIA/TESS.jpg: open failed: ENOENT (No such file or directory)
01-26 10:21:45.502: E/JHEAD(1389): can't open '/mnt/sdcard/DCIM/100MEDIA/TESS.jpg'
01-26 10:21:45.512: D/AndroidRuntime(1389): Shutting down VM
01-26 10:21:45.512: W/dalvikvm(1389): threadid=1: thread exiting with uncaught exception (group=0x417b0930)
01-26 10:21:45.522: E/AndroidRuntime(1389): FATAL EXCEPTION: main
01-26 10:21:45.522: E/AndroidRuntime(1389): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=0, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.cam.calc/cam.calc.Main}: java.lang.NullPointerException
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.app.ActivityThread.deliverResults(ActivityThread.java:3319)
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3362)
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.app.ActivityThread.access$1100(ActivityThread.java:141)
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1282)
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.os.Handler.dispatchMessage(Handler.java:99)
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.os.Looper.loop(Looper.java:137)
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.app.ActivityThread.main(ActivityThread.java:5039)
01-26 10:21:45.522: E/AndroidRuntime(1389): at java.lang.reflect.Method.invokeNative(Native Method)
01-26 10:21:45.522: E/AndroidRuntime(1389): at java.lang.reflect.Method.invoke(Method.java:511)
01-26 10:21:45.522: E/AndroidRuntime(1389): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
01-26 10:21:45.522: E/AndroidRuntime(1389): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
01-26 10:21:45.522: E/AndroidRuntime(1389): at dalvik.system.NativeStart.main(Native Method)
01-26 10:21:45.522: E/AndroidRuntime(1389): Caused by: java.lang.NullPointerException
01-26 10:21:45.522: E/AndroidRuntime(1389): at cam.calc.Main.onActivityResult(Main.java:388)
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.app.Activity.dispatchActivityResult(Activity.java:5293)
01-26 10:21:45.522: E/AndroidRuntime(1389): at android.app.ActivityThread.deliverResults(ActivityThread.java:3315)
01-26 10:21:45.522: E/AndroidRuntime(1389): ... 11 more
You need to process the images before OCR, at least convert the image to black&white (gray scale) can enhance the result :
bitmap = toGrayscale(bitmap);
bitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
you can user OpenCV or any Image Processing Library, for for simple task like grayscale its enopugh to use
import android.graphics.*;
public static Bitmap toGrayscale(Bitmap bmpOriginal)
{
int width, height;
height = bmpOriginal.getHeight();
width = bmpOriginal.getWidth();
Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpGrayscale);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
cm.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bmpOriginal, 0, 0, paint);
return bmpGrayscale;
}
Also if the image is too large you may need to crop the image and get the area that contain the characters & numbers you want to recognize, its also make OCR engine job more easier/more accuracy and sometimes its prevents you from OutOfMemoryException.

Categories