Is it possible to save a photo taken with a camera in color mode as black and white or must the camera paramaters be changed so the viewfinder sees black and white when the picture is taken? Here is the code I am using to save an image in color, I want to save it as black and white to save space.
PictureCallback jpegCallback = new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
Log.e("Pic Taken","Callback");
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 1;
options.inDither = false; // Disable Dithering mode
options.inPurgeable = true; // Tell to gc that whether it needs free
// memory, the Bitmap can be cleared
options.inInputShareable = true; // Which kind of reference will be
// used to recover the Bitmap
// data after being clear, when
// it will be used in the future
options.inTempStorage = new byte[32 * 1024];
options.inPreferredConfig = Bitmap.Config.RGB_565;
Bitmap bMap = BitmapFactory.decodeByteArray(data, 0, data.length, options);
int orientation;
// others devices
if(bMap.getHeight() < bMap.getWidth()){
orientation = 90;
} else {
orientation = 0;
}
Bitmap bMapRotate;
if (orientation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(orientation);
bMapRotate = Bitmap.createBitmap(bMap, 0, 0, bMap.getWidth(),
bMap.getHeight(), matrix, true);
} else
bMapRotate = Bitmap.createScaledBitmap(bMap, bMap.getWidth(),
bMap.getHeight(), true);
FileOutputStream out;
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
try {
Log.e("Saving","Pic");
String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String fileName = "/" + System.currentTimeMillis() + ".jpg";
out = new FileOutputStream(baseDir + fileName);
bMapRotate.compress(Bitmap.CompressFormat.JPEG, 25, out);
if (bMapRotate != null) {
bMapRotate.recycle();
bMapRotate = null;
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
You can convert Bitmap:
public Bitmap convertToGrayScale(Bitmap original) {
Bitmap result = Bitmap.createBitmap(original.getWidth(), original.getHeight(), Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
ColorMatrix matrix = new ColorMatrix();
matrix.setSaturation(0);
ColorMatrixColorFilter f = new ColorMatrixColorFilter(matrix);
paint.setColorFilter(f);
canvas.drawBitmap(original, 0, 0, paint);
return result;
}
You can convert an existing photo into Black and White. After:
else
bMapRotate = Bitmap.createScaledBitmap(bMap, bMap.getWidth(),
bMap.getHeight(), true);
Add this:
Bitmap newBitmap = Bitmap.createBitmap(bMapRotate.getWidth(), bMapRotate.getHeight(), Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(newBitmap);
Paint paint = new Paint();
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);
ColorMatrixColorFilter cmFilter = new ColorMatrixColorFilter(colorMatrix);
paint.setColorFilter(cmFilter);
canvas.drawBitmap(bMapRotate, 0, 0, paint);
And don't forget to call .recycle() on bMapRotate.
It should be available in the Camera.parameters.
Depending on if the device's camera supports it, you could use it.
Use this code to retrieve them:
Camera.Parameters params = cam.getParameters();
try {
for (String e : params.getSupportedColorEffects()) {
Log.d(TAG, "Effect: " + e);
}
}
catch (NullPointerException npe) {
Log.d(TAG, "No color effects supported by this camera.");
}
And read the documentation:
http://developer.android.com/reference/android/hardware/Camera.Parameters.html
Related
I want exactly the functionality of Camera (Like Single and Batch(Multiple Photos at a time)) in the following app:
https://play.google.com/store/apps/details?id=com.thegrizzlylabs.geniusscan.free&hl=en
I have implemented Successfully this. But, my question is, I have implemented this functionality with SurfaceView. When I capture photos from camera, its blurred when compared to the Genius Scan App.
Could anyone please let me know how exactly i can achieve this functionality without getting blurred.
NOTE: Capturing Multiple Photos
private void takeImage() {
camera.takePicture(null, null, new PictureCallback() {
private File imageFile;
#Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
// convert byte array into bitmap
Bitmap loadedImage = null;
Bitmap rotatedBitmap = null;
loadedImage = BitmapFactory.decodeByteArray(data, 0,
data.length);
// rotate Image
Matrix rotateMatrix = new Matrix();
rotateMatrix.postRotate(rotation);
rotatedBitmap = Bitmap.createBitmap(loadedImage, 0, 0,
loadedImage.getWidth(), loadedImage.getHeight(),
rotateMatrix, false);
String state = Environment.getExternalStorageState();
File folder = null;
if (state.contains(Environment.MEDIA_MOUNTED)) {
folder = new File(Environment
.getExternalStorageDirectory() + "/Demo");
} else {
folder = new File(Environment
.getExternalStorageDirectory() + "/Demo");
}
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
java.util.Date date = new java.util.Date();
imageFile = new File(folder.getAbsolutePath()
+ File.separator
+ new Timestamp(date.getTime()).toString()
+ "Image.jpg");
imageFile.createNewFile();
} else {
Toast.makeText(getBaseContext(), "Image Not saved",
Toast.LENGTH_SHORT).show();
return;
}
ByteArrayOutputStream ostream = new ByteArrayOutputStream();
// save image into gallery
rotatedBitmap.compress(CompressFormat.JPEG, 100, ostream);
FileOutputStream fout = new FileOutputStream(imageFile);
fout.write(ostream.toByteArray());
fout.close();
ContentValues values = new ContentValues();
values.put(Images.Media.DATE_TAKEN,
System.currentTimeMillis());
values.put(Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA,
imageFile.getAbsolutePath());
CameraDemoActivity.this.getContentResolver().insert(
Images.Media.EXTERNAL_CONTENT_URI, values);
if (mSingleView.getVisibility() == View.VISIBLE) {
btnDoneClicked();
} else {
}
mArrayUri.add(Uri.fromFile(imageFile));
if (mBatchView.getVisibility() == View.VISIBLE) {
batchClickCount++;
mtxtCapturedClicks.setText(String.valueOf(batchClickCount));
} else {
batchClickCount = 0;
mtxtCapturedClicks.setText("");
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public static Bitmap scaleBitmap(Bitmap bitmap, int newWidth, int newHeight) {
Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
float scaleX = newWidth / (float) bitmap.getWidth();
float scaleY = newHeight / (float) bitmap.getHeight();
float pivotX = 0;
float pivotY = 0;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(scaleX, scaleY, pivotX, pivotY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
Try this function to improve the image quality
I want to merge two bitmaps, here is my code
// Camera arg conversion to Bitmap
Bitmap cameraBitmap = BitmapFactory.decodeByteArray(arg0, 0,
arg0.length);
Bitmap back = Bitmap.createBitmap(cameraBitmap.getWidth(),
cameraBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas cam = new Canvas(back);
cam.drawBitmap(cameraBitmap, matrix, null);
// FrameLayout to Bitmap
FrameLayout mainLayout = (FrameLayout) findViewById(R.id.frame);
Bitmap foreground = Bitmap.createBitmap(mainLayout.getWidth(),
mainLayout.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(foreground);
mainLayout.draw(c);
Bitmap cs = null;
cs = Bitmap.createBitmap(foreground.getWidth(), cameraBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(cameraBitmap, 0f, 0f, null);
comboImage.drawBitmap(foreground, 0f, cameraBitmap.getHeight(), null);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
if (fos != null) {
cs.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
The camera image should become background, and foreground as top image. I've tried from
Combining 2 Images in Android using Canvas but it didn't help me. Any idea.? Thanks
From your example, you forgot to add the next lines:
comboImage.drawBitmap(c, 0f, 0f, null);
comboImage.drawBitmap(s, 0f, c.getHeight(), null);
In your example above you don't draw your image in the canvas, and that is the problem.
You can think that your canvas i your sketchbook. For now you didn't paint anything, and you ask yourself, way I can't see any colors.
So, for my advice, first create the two bitmaps, then, do the next thing:
c.drawBitmap(cameraBitmap, top point, left point, null);
c.drawBitmap(foreground, top point, left point, null);
You can also do this by first create the drawable objects from your bitmaps, like in the next code:
Drawable cameraBitmap = BitmapDrawable(cameraBitmap);
Drawable foreground= BitmapDrawable(foreground);
Then when you have the drawable objects, you can set thier bounds, and that way you set where do you want to show that image.
cameraBitmap.setBounds(left, top, right, bottom);
foreground.setBounds(left, top, right, bottom);
and finally draw that on the canvas:
cameraBitmap.draw(canvas);
foreground.draw(canvas);
EDIT:
This is an example, use this to understand your implementation:
Bitmap bitmap = null;
try {
bitmap = Bitmap.createBitmap(500, 500, Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
Resources res = getResources();
Bitmap bitmap1 = BitmapFactory.decodeResource(res, R.drawable.test1); //blue
Bitmap bitmap2 = BitmapFactory.decodeResource(res, R.drawable.test2); //green
Drawable drawable1 = new BitmapDrawable(bitmap1);
Drawable drawable2 = new BitmapDrawable(bitmap2);
drawable1.setBounds(100, 100, 400, 400);
drawable2.setBounds(150, 150, 350, 350);
drawable1.draw(c);
drawable2.draw(c);
} catch (Exception e) {
}
return bitmap;
This is what I get from the code above:
Merging Two Bitmap vertically when one is large and second is small
follow this method
public Bitmap finalcombieimage(Bitmap c, Bitmap s) {
Bitmap cs = null;
DisplayMetrics metrics = getBaseContext().getResources().getDisplayMetrics();
int width = metrics.widthPixels;
int height = metrics.heightPixels;
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
Rect dest1 = new Rect(0, 0, width, height); // left,top,right,bottom
comboImage.drawBitmap(c, null, dest1, null);
Rect dest2 = new Rect(0, height-400 / 2, width, height);
comboImage.drawBitmap(s, null, dest2, null);
return cs;
}
Please note that the BitmapDrawable(Bitmap) has been deprecated. Kinldy check this for the alternative.
BitmapDrawable(Bitmap bitmap)
This constructor was deprecated in API level 4. Use BitmapDrawable(Resources, Bitmap) to ensure that the drawable has correctly set its target density.
Resize watermark image same size as original image
Uri bmpUri1 = getLocalBitmapUri(ivImage);
Uri bmpUri2 = getLocalBitmapUri(watermark_imageview);
try {
bm1 = BitmapFactory.decodeStream(
getContentResolver().openInputStream(bmpUri1));
bm2 = BitmapFactory.decodeStream(
getContentResolver().openInputStream(bmpUri2));
Bitmap bmOverlay = Bitmap.createBitmap(bm1.getWidth(), bm1.getHeight(), bm1.getConfig());
bm2 = Bitmap.createScaledBitmap(bm2, bm1.getWidth(), bm1.getHeight(),
true);
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bm1, 0,0, null);
canvas.drawBitmap(bm2, 0,0, null);
watermarkimage.setVisibility(View.GONE);
im =new ImageView(ImageClick.this);
im.setImageBitmap(bmOverlay);
bmpUri = getLocalBitmapUri(im);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
private Uri getLocalBitmapUri(ImageView imageView) {
Drawable drawable = imageView.getDrawable();
Bitmap bmp = null;
if (drawable instanceof BitmapDrawable){
bmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
} else {
return null;
}
// Store image to default external storage directory
Uri bmpUri = null;
try {
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "share_image_" + System.currentTimeMillis() + ".png");
file.getParentFile().mkdirs();
FileOutputStream out = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 90, out);
out.close();
bmpUri = Uri.fromFile(file);
} catch (IOException e) {
e.printStackTrace();
}
return bmpUri;
}
I'm using the code below. My app was able to draw on the canvas and save it.
But what I want to do is make an image as the background of the canvas so when I save it, it will look like an image with the user's drawing on top of it.
Thank you so much for any help! :)
#Override
public void run() {
Canvas canvas = null;
while (_run){
if(isDrawing == true){
try{
canvas = mSurfaceHolder.lockCanvas(null);
if(mBitmap == null){
mBitmap = Bitmap.createBitmap (1, 1, Bitmap.Config.ARGB_8888);
}
final Canvas c = new Canvas (mBitmap);
c.drawColor(0, PorterDuff.Mode.CLEAR);
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
canvas.drawColor(0xffffffff);
commandManager.executeAll(c,previewDoneHandler);
previewPath.draw(c);
canvas.drawBitmap (mBitmap, 0, 0,null);
} finally {
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
Try this stuff,
This will return a Bitmap that will be a Merged one of two Bitmap Images, also it will save in the SDCard.
public Bitmap combineImages(Bitmap c, Bitmap s) {
Bitmap cs = null;
int width, height = 0;
if (c.getWidth() > s.getWidth()) {
width = c.getWidth();
height = c.getHeight();
} else {
width = s.getWidth() + s.getWidth();
height = c.getHeight();
}
cs = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas comboImage = new Canvas(cs);
comboImage.drawBitmap(c, 0, 0, null);
comboImage.drawBitmap(s, 100, 300, null);
/******
*
* Write file to SDCard
*
* ****/
String tmpImg = String.valueOf(System.currentTimeMillis()) + ".png";
OutputStream os = null;
try {
os = new FileOutputStream(Environment.getExternalStorageDirectory()
+ "/"+tmpImg);
cs.compress(CompressFormat.PNG, 100, os);
} catch (IOException e) {
Log.e("combineImages", "problem combining images", e);
}
return cs;
}
For any view that you are creating, you can create a bitmap of what it is currently displaying.
use:
view.setDrawingCacheEnabled(true);
Bitmap bitmap=view.getDrawingCache();
Does this help you in achieving what you want ?
*be sure to recycle these bitmaps when you are done.
bitmap.recycle();
my api is 2.2,so i used camera.setDisplayOrientation(90) to make the preview is Portrait,this work very well,but when i save the pic to sd,the pic is horizontal not Portrait.when i used :
#Override
protected Bitmap doInBackground(String... params) {
int w = bmp.getWidth();
int h = bmp.getHeight();
// Setting post rotate to 90
Matrix mtx = new Matrix();
mtx.postRotate(90);
// Rotating Bitmap
Bitmap rotatedBMP = Bitmap.createBitmap(bmp, 0, 0, w, h, mtx, true);
bmp.recycle();
return rotatedBMP;
}
#Override
protected void onPostExecute(Bitmap result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
ivNewPhoto.setImageBitmap(result);
resultPath = ConstValue.MY_ALBUM_DIR + "/" + System.currentTimeMillis() + ".jpg";
ImageFile.writePhotoJpg(result), resultPath);
previewView.setVisibility(View.VISIBLE);
}
bmp is the Snapshot pic but i have mistakes:
Activity com.android.SuperPictureSearch.photo.PhotoActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView#43abb200 that was originally added here
can you tell me how to save the pic is Portrait,thank you
public void onPictureTaken(byte[] data, Camera camera) {
Bitmap mutableBitmap = null;
BitmapFactory.Options options = new BitmapFactory.Options();
Bitmap bm= BitmapFactory.decodeByteArray(data, 0, data.length, options);
mutableBitmap =Bitmap.createScaledBitmap( bm , h, w,true);
bm.recycle();
Matrix matri = new Matrix();
matri.postRotate(90);
Bitmap mBitmap = Bitmap.createBitmap(mutableBitmap, 0, 0, mutableBitmap.getWidth(), mutableBitmap.getHeight(), matri, true);
mutableBitmap.recycle();
because the pic is too big form camera,so i size it
I have a simple function for creating image overlay.
public String getMyPath(Application app, Context c) {
String path = Environment.getExternalStorageDirectory() + "image.jpg";
Bitmap bmap = BitmapFactory.decodeFile(photo);
Bitmap mutableBitmap = bmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
canvas.drawPaint(paint);
paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inDither = true;
opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap itemBitmapOrg = BitmapFactory.decodeResource(c.getResources(), R.drawable.star, opt);
Matrix matrix = new Matrix();
matrix.postTranslate(0, 0);
canvas.drawBitmap(bmap, 0, 0, null);
canvas.drawBitmap(itemBitmapOrg,matrix,paint);
FileOutputStream out=null;
try {
out = new FileOutputStream(new File(path));
} catch (FileNotFoundException e) {
}
mutableBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
}
return path;
}
My overlay image size is 72x72.
Problem comes when try to overlay very small image for example resolution 57x88. Then the overlay sign is not proper displayed!
How to proper scale the overlay sign to be adequate for all resolutions ?