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
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.
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)
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);
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;
}
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.