[Edit: I've made a minimal project to try to narrow down what's going on. The code at the bottom still generates the same artifacts when saved]
I have an app that draws simple 2D geometry using Paths. The shapes are all solid colors, sometimes with alpha < 255, and may be decorated with lines. In the View that draws the geometry, there has never been an issue with how things get drawn. However, when I use the same code to draw to a Bitmap, and then save it as either a JPEG (with 100 quality) or PNG, there is always the same artifacting in the solid-colored areas of the output files. It's a sort of mottling that is usually associated with JPEG compression.
Screenshot of View:
Saved image:
Zoom in on artifacts:
I have tried the following
Saving to either PNG and JPEG
Turning dithering and antialiasing on and off
Increasing the DPI of the Bitmap, and also allowed the Bitmap to use its default API
Applying the matrix I use as a camera to the geometric representation, instead of applying it to the Canvas for the bitmap
Turning HW Acceleration on and off app-wide
Using a 3rd party library to save the Bitmap to a .bmp file
All yield the same artifacts, neither making it worse nor better.
public class MainActivity extends AppCompatActivity {
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.context = getApplicationContext();
}
// button OnClick listener
public void saveImage(View view) {
new saveBitmapToDisk().execute(false);
}
public Bitmap getBitmap() {
final int bitmapHeight = 600, bitmapWidth = 600;
Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
Canvas bitmapCanvas = new Canvas(bitmap);
float[] triangle = new float[6];
triangle[0] = bitmapWidth / 2;
triangle[1] = 0;
triangle[2] = 0;
triangle[3] = bitmapHeight / 2;
triangle[4] = bitmapWidth / 2;
triangle[5] = bitmapHeight / 2;
Path solidPath = new Path();
Paint solidPaint = new Paint();
solidPaint.setStyle(Paint.Style.FILL);
solidPath.moveTo(triangle[0], triangle[1]);
for(int i = 2; i < triangle.length; i += 2)
solidPath.lineTo(triangle[i], triangle[i+1]);
solidPath.close();
solidPaint.setColor(Color.GREEN);
bitmapCanvas.drawPath(solidPath, solidPaint);
return bitmap;
}
private class saveBitmapToDisk extends AsyncTask<Boolean, Integer, Uri> {
Boolean toShare;
#Override
protected Uri doInBackground(Boolean... shareFile) {
this.toShare = shareFile[0];
final String appName = context.getResources().getString(R.string.app_name);
final String IMAGE_SAVE_DIRECTORY = String.format("/%s/", appName);
final String fullPath = Environment.getExternalStorageDirectory().getAbsolutePath() + IMAGE_SAVE_DIRECTORY;
File dir, file;
try {
dir = new File(fullPath);
if (!dir.exists())
dir.mkdirs();
OutputStream fOut;
file = new File(fullPath, String.format("%s.png", appName));
for (int suffix = 0; file.exists(); suffix++)
file = new File(fullPath, String.format("%s%03d.png", appName, suffix));
file.createNewFile();
fOut = new FileOutputStream(file);
Bitmap saveBitmap = getBitmap();
saveBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
} catch (OutOfMemoryError e) {
Log.e("MainActivity", "Out of Memory saving bitmap; bitmap is too large");
return null;
} catch (Exception e) {
Log.e("MainActivity", e.getMessage());
return null;
}
return Uri.fromFile(file);
}
#Override
protected void onPostExecute(Uri uri) {
super.onPostExecute(uri);
Toast.makeText(context, "Image saved", Toast.LENGTH_SHORT).show();
}
}
}
I tested your program with PNG and the file has no artifacts
These artifacts are a result of JPEG compression
Edit:
The line
MediaStore.Images.Media.insertImage(context.getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
was causing the conversion to jpeg.
The proper way to save the image is
ContentValues values = new ContentValues();
values.put(Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(Images.Media.MIME_TYPE, "image/png");
values.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
context.getContentResolver().insert(Images.Media.EXTERNAL_CONTENT_URI, values);
Here is my simplified test program that sends the generated file directly
public class Test2Activity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new saveBitmapToDisk().execute();
}
public Bitmap getBitmap() {
final int bitmapHeight = 600, bitmapWidth = 600;
Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
Canvas bitmapCanvas = new Canvas(bitmap);
Paint solidPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
solidPaint.setStyle(Paint.Style.FILL);
solidPaint.setColor(Color.RED);
bitmapCanvas.drawCircle(300, 300, 200, solidPaint);
return bitmap;
}
private class saveBitmapToDisk extends AsyncTask<Void, Void, Uri> {
Boolean toShare;
#Override
protected Uri doInBackground(Void... shareFile) {
Context context = Test2Activity.this;
try {
File file = new File(context.getExternalFilesDir(null), "test.png");
FileOutputStream fOut = new FileOutputStream(file);
Bitmap saveBitmap = getBitmap();
saveBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
return Uri.fromFile(file);
} catch (OutOfMemoryError e) {
Log.e("MainActivity", "Out of Memory saving bitmap; bitmap is too large");
return null;
} catch (Exception e) {
Log.e("MainActivity", e.getMessage());
return null;
}
}
#Override
protected void onPostExecute(Uri uri) {
Context context = Test2Activity.this;
Toast.makeText(context, "Image saved", Toast.LENGTH_SHORT).show();
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("image/png");
Test2Activity.this.startActivity(intent);
}
}
}
Artifacts like this are natural and unavoidable consequence of JPEG compression.
They should not crop up in PNG compression. If you are getting such artifacts when you create a PNG file, I'd wager that you are not creating a PNG stream at all, but rather a JPEG stream in a file with a PNG extension. No decent decoder relies on the file extension.
I noticed two things in your code:
1) The filename you save to is String.format("%s.jpg", appName) or String.format("%s%03d.png", appName, suffix) independent of the actual encoding.
2) The bitmap you save has its density determined by prefs.saveImageDensity().get() so it may not be the same as the actual density of the bitmap you see on the screen.
Maybe you confused yourself with 1) or perhaps 2) causes the compression-artefacts you're seeing?
Related
I am taking screenshot programmatically using the following code:
public static Bitmap takeScreenshot(View view)
{
try
{
// create bitmap screen capture
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return bitmap;
}
catch (Throwable e)
{
CustomLogHandler.printError(e);
}
return null;
}
private static void copyFile(Bitmap bitmap)
{
File dstFile = getShareResultFile();
//Delete old file if exist.
if(dstFile.exists()) {
dstFile.delete();
}
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(dstFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 0, fos);
fos.flush();
}
catch (Exception e) {
CustomLogHandler.printError(e);
}
finally {
if (fos != null) {
try {
fos.close();
} catch (IOException ioe) {
CustomLogHandler.printError(ioe);
}
}
}
}
There are several problem like:
Back arrow, title and share menu background color is not correct. It looks messy.
Background color of toolbar is totally changed.
Image quality is too poor and list items rounded drawable has not smooth corners.
Background of layout is not taken that I set as background of my parent layout.
I am taking the screenshot from the root view.
bitmap.compress(Bitmap.CompressFormat.JPEG, 0, fos);
First, you are saving this as a JPEG. JPEG is designed for photos, and your screenshot is not a photo.
Second, you are saving this with a quality factor of 0. JPEG uses a lossy compression algorithm, and a quality factor of 0 says "please feel free to make this image be really poor, but compress it as far as you can".
I suggest switching to:
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
PNG is a better image format for a screenshot with the contents shown in your question. I don't think PNG uses the quality factor value; I put in 100 just to indicate that you want the best possible quality.
public static Bitmap takeScreenshot(View view)
{
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
This code can save view as bitmap.
But after you update your question with save code I see that you set 0 for quality, and what you expect?
#param quality Hint to the compressor, 0-100. 0 meaning compress for
* small size, 100 meaning compress for max quality. Some
* formats, like PNG which is lossless, will ignore the
* quality setting
just use your Ctrl button + click on method name to read doc about params
the answer is set second parameter 100 instead of 0!
Try using this:
public static Bitmap loadBitmapFromView(Context context, View v) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
v.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap returnedBitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(returnedBitmap);
v.draw(c);
return returnedBitmap;
}
and
public void takeScreen() {
Bitmap bitmap = ImageUtils.loadBitmapFromView(this, view); //get Bitmap from the view
String mPath = Environment.getExternalStorageDirectory() + File.separator + "screen_" + System.currentTimeMillis() + ".jpeg";
File imageFile = new File(mPath);
OutputStream fout = null;
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
fout.close();
}
}
Images are saved in the external storage folder.
try this
private void captureScreen() {
View v = this.getWindow().getDecorView().findViewById(android.R.id.content);
v.setDrawingCacheEnabled(true);
Bitmap bitmap = v.getDrawingCache();
String extr = Environment.getExternalStorageDirectory().toString();
File file = new File(extr, getString(R.string.free_tiket) + ".jpg");
FileOutputStream f = null;
try {
f = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, f);
f.flush();
f.close();
MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "Screen", "screen");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
I know it's a very basic question but i am stuck to resolve this problem. I am working on image-sketching mobile app i have done all the work now I just want to store a resulting bitmap-image into internal memory.I have created a method "mageStore()" for image-storing purposes please write code there. I will be very thankful to you.
`private class ImageProcessingTask extends AsyncTask<Bitmap, Void, Bitmap> {
private ProgressDialog abhanDialog = null;
private Bitmap returnedBitmap = null;
#Override
protected void onPreExecute() {
returnedBitmap = null;
abhanDialog = new ProgressDialog(AbhanActivity.this);
abhanDialog.setMessage(getString(R.string.please_wait));
abhanDialog.setCancelable(false);
abhanDialog.show();
}
#Override
protected Bitmap doInBackground(Bitmap... params) {
final Bitmap sketched = AbhanSketch.createSketch(params[0]);
final Bitmap gaussianBitmap = AbhanEffects.applyGaussianBlur(sketched);
final Bitmap sepiaBitmap = AbhanEffects.sepiaTonnedBitmap(gaussianBitmap, 151, 0.71,
0.71, 0.76);
returnedBitmap = AbhanEffects.sharpenBitmap(sepiaBitmap, 0.81);
return returnedBitmap;
}
#Override
protected void onPostExecute(Bitmap result) {
if (abhanDialog != null && abhanDialog.isShowing()) {
abhanDialog.cancel();
}
if (result != null) {
mImageView.setImageBitmap(result);
mImageView.buildDrawingCache();
bmap = mImageView.getDrawingCache();
storeImage(bmap);
isImage = false;
enableButton();
final boolean isFileDeleted = Utils.deleteFile(mPath);
if (DEBUG) {
android.util.Log.i(TAG, "File Deleted: " + isFileDeleted);
}
}
}
}
private void storeImage(Bitmap image) {
...please enter code here for image storing
}`
Here is your missing code inside a function
private void storeImage(Bitmap image) {
File sdcard = Environment.getExternalStorageDirectory() ;
File folder = new File(sdcard.getAbsoluteFile(), "YOUR_APP_DIRECTORY");
if(!folder.exists())
folder.mkdir();
File file = new File(folder.getAbsoluteFile(), "IMG_" + System.currentTimeMillis() + ".jpg") ;
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap = Bitmap.createScaledBitmap(bitmap, 400, (int) ( bitmap.getHeight() * (400.0 / bitmap.getWidth()) ) ,false);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
You can omit or edit this line
bitmap = Bitmap.createScaledBitmap(bitmap, 400, (int) ( bitmap.getHeight() * (400.0 / bitmap.getWidth()) ) ,false);
according to your need.
in your function write the following code
String path = Saveme(image,"image_name.jpg");
//path contains the full path to directory where all your images get stored internaly lolz but privately
for gallery
Saveme(image,"my image","my image test for gallery save");
and the defination for the Saveme() function is following
private String Saveme(Bitmap bitmapImage, String img_name){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
// Create imageDir
File mypath=new File(directory,img_name);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return directory.getAbsolutePath();
}
in gallery images are displayed from media store so you need to store image in media store the following code can help you for this
public void Saveme(Bitmap b, String title, String dsc)
{
MediaStore.Images.Media.insertImage(getContentResolver(), b, title ,dsc);
}
I want to design an app that generates a QR code and gives the user the possibility to save the generated image to their internal storage only. I successfully generate the bitmap and save it as .PNG image, but when I try to open it from the gallery it appears broken or corrupt.
Below is the code to generate the bitmap and display it on an ImageView(qrCode):
bitmap = encodeAsBitmap(value);
qrCode.setImageBitmap(bitmap);
Bitmap encodeAsBitmap(String str) throws WriterException {
BitMatrix result;
try {
result = new MultiFormatWriter().encode(str,
BarcodeFormat.QR_CODE, WIDTH, WIDTH, null);
} catch (IllegalArgumentException iae) {
// Unsupported format
return null;
}
int w = result.getWidth();
int h = result.getHeight();
int[] pixels = new int[w * h];
for (int y = 0; y < h; y++) {
int offset = y * w;
for (int x = 0; x < w; x++) {
pixels[offset + x] = result.get(x, y) ? getResources().getColor(R.color.colorBlack) :
getResources().getColor(R.color.colorWhite);
}
}
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, 500, 0, 0, w, h);
return bitmap;
}
It works perfectly up to this level. The user can then click a button in order to save this image to their device's internal storage, thanks to the below method:
public void onClickSaveCode(View view) {
String title = getResources().getString(R.string.saved_image_title_prepend) + stringDate;
String format = getResources().getString(R.string.saved_image_format);
String directory = getResources().getString(R.string.saved_image_directory);
// Method call to save image
saveImageToInternalStorage(bitmap, directory, title, format);
}
public boolean saveImageToInternalStorage(Bitmap bitmap, String directory, String title, String format) {
ContextWrapper contextWrapper = new ContextWrapper(getApplicationContext());
File imageDirectory = contextWrapper.getDir(directory, Context.MODE_WORLD_READABLE);
File path = new File(imageDirectory, title + format);
try {
FileOutputStream fos = new FileOutputStream(path);
// Use the compress method on the Bitmap object to write image to the OutputStream
bitmap.compress(Bitmap.CompressFormat.PNG, QUALITY, fos);
fos.close();
new SingleMediaScanner(this, path);
Toast.makeText(this, getString(R.string.save_success), Toast.LENGTH_LONG).show();
return true;
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, getString(R.string.save_failure), Toast.LENGTH_LONG).show();
return false;
}
}
And finally below is the MediaScannerConnection class to scan for all images saved to the device and display them in the gallery:
public class SingleMediaScanner implements MediaScannerConnectionClient {
private MediaScannerConnection mSC;
private File file;
public SingleMediaScanner(Context context, File f) {
file = f;
mSC = new MediaScannerConnection(context, this);
mSC.connect();
}
#Override
public void onMediaScannerConnected() {
mSC.scanFile(file.getAbsolutePath(), null);
}
#Override
public void onScanCompleted(String path, Uri uri) {
mSC.disconnect();
}
}
The images are saved, yet they appear in the gallery as broken files.
Any help will be greatly appreciated.
string path = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
string filePath = System.IO.Path.Combine(path, "compressed.png");
//Bitmap bmp = ((BitmapDrawable)imgV.Drawable).Bitmap;
Bitmap b = newBitmap;
FileStream ms = new FileStream(filePath, FileMode.Create);
//FileOutputStream fos = new FileOutputStream(filePath,true);
await b.CompressAsync(Bitmap.CompressFormat.Png, 100, ms);
ms.Close();
//ByteArrayOutputStream opstream = new ByteArrayOutputStream();
//b.Compress(Bitmap.CompressFormat.Png, 100, opstream);
//byte[] bytArray = opstream.ToByteArray();
Toast.MakeText(Application.Context, "Compressed : " , ToastLength.Short).Show();
imgCompress.SetImageBitmap(b);
I'm building an android tesseract app. It was reading the data fine until I was taking photos from the default camera app. Now, I needed to implement my own custom camera, that caused it to start giving wrong result.
public class getButtonClicked implements View.OnClickListener{
public void onClick(View arg0) {
DATA_PATH = Environment.getExternalStorageDirectory().toString() + "/MyOCRApp/";
File tessdata = new File(DATA_PATH);
if (!tessdata.isDirectory()){
throw new IllegalArgumentException("Data path must contain subfolder tessdata!");
}
TessBaseAPI baseApi = new TessBaseAPI();
baseApi.setDebug(true);
baseApi.init(DATA_PATH, lang);
if (newImg == null){
baseApi.setImage(imageBitmap);
}
else{
baseApi.setImage(newImg);
}
String recognizedText = baseApi.getUTF8Text();
// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(context);
// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage("Recognized Text:\n\n" + recognizedText);
// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();
dialog.show();
//baseApi.end();
}
}
This is the code that calls the tesseract APIs.
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d("Error creating file" ,"!");
return;
}
int screenWidth = getResources().getDisplayMetrics().widthPixels;
int screenHeight = getResources().getDisplayMetrics().heightPixels;
bm = BitmapFactory.decodeByteArray(data, 0, (data != null) ? data.length : 0);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// Notice that width and height are reversed
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenHeight, screenWidth, true);
int w = scaled.getWidth();
int h = scaled.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
MainActivity.imageBitmap = Bitmap.createBitmap(scaled, 0, 0, w, h, mtx, true);
}else{// LANDSCAPE MODE
//No need to reverse width and height
Bitmap scaled = Bitmap.createScaledBitmap(bm, screenWidth,screenHeight , true);
MainActivity.imageBitmap = scaled;
}
Calendar c = Calendar.getInstance();
String time = Integer.toString(c.get(Calendar.DATE));
//MediaStore.Images.Media.insertImage(getContentResolver(), MainActivity.imageBitmap, time+"MyOCR", "Hello!!");
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/MyOCRApp");
if (! myDir.exists()){
if (! myDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return;
}
}
String fname = "Image-" +time+ ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
MainActivity.imageBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
MediaStore.Images.Media.insertImage(getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());
} catch (Exception e) {
e.printStackTrace();
}
surfaceDestroyed(mSurfaceHolder);
}
};
This is the code in my camera class. I even debugged and checked that the picture was perfectly fine, when the tesseract APIs are called. I can't post photos, otherwise I have posted one. What should I do??
I am experimenting with tesseract on android as well. Try to rescale your image. An image taken by the camera activity maybe to big. Additionaly you probably have to pre-process the image (contrast, horizontal alignment of text, ...)
I am doing a Face Recognition project for my final year. I have to do face Recognition on Android using Local Binary Pattern(LBP).
I searched a lot on the internet for codes for face recognition using LBP in java, but couldn't find anything implementable on android. So now I am forced to writing it all, and I am a kind of a newbie to android as well as image processing.
I have found out a way to capture images from the camera.
public class CameraCapture extends Activity {
protected boolean _taken = true;
File sdImageMainDirectory;
protected static final String PHOTO_TAKEN = "photo_taken";
#Override
public void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
File root = new File(Environment
.getExternalStorageDirectory()
+ File.separator + "myDir" + File.separator);
root.mkdirs();
sdImageMainDirectory = new File(root, "myPicName");
startCameraActivity();
}
catch (Exception e) {
finish();
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
}
protected void startCameraActivity() {
Uri outputFileUri = Uri.fromFile(sdImageMainDirectory);
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri);
startActivityForResult(intent, 0);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (resultCode) {
case 0:
finish();
break;
case -1:
try {
StoreImage(this, Uri.parse(data.toURI()),
sdImageMainDirectory);
} catch (Exception e) {
e.printStackTrace();
}
finish();
startActivity(new Intent("com.piit.lbp.form.LBPFORMADD"));
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState.getBoolean(CameraCapture.PHOTO_TAKEN)) {
_taken = true;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(CameraCapture.PHOTO_TAKEN, _taken);
}
public static void StoreImage(Context mContext, Uri imageLoc, File imageDir) {
Bitmap bm = null;
try {
bm = Media.getBitmap(mContext.getContentResolver(), imageLoc);
bmGray = toGrayScale(bm);
FileOutputStream out = new FileOutputStream(imageDir);
bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
bm.recycle();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Question : What is the "Bitmap bm" - like RGB_565, or something else ?? and how many bits.
Before compressing bitmap to jpeg I call a RGB to Grayscale method with the following code
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;
}
And then I wish to use bmGray for applying LBP operator.
Question : When you convert to Grayscale using ColorMatrix, is it 8bits per pixel ??
Cos I want to convert bmGray to Byte Array and want to extract only 1 byte at a time. And also I want to know if can convert the grayscale image to a 2d matrix of pixel values, I know that it is already a 2d matrix of pixel values, but how can i work on it.. like selecting the pixel above and below the current pixel. ??
for the CameraPicture this applies:
If setPreviewFormat(int) is never called, the default will be the
YCbCr_420_SP (NV21) format.
http://developer.android.com/reference/android/hardware/Camera.Parameters.html#setPreviewFormat%28int%29
Bitmap bmp you can configure like:
Bitmap bmp = Bitmap.createBitmap(frameWidth, frameHeight, Bitmap.Config.ARGB_8888); //or RGB_565 if you prefer.
for accessing bmp data I only found something like this: http://upload.wikimedia.org/wikipedia/commons/c/c4/BMPfileFormat.png
hope it helps