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 ?
Related
I would like to add a watermark image (my logo) from my drawable before sharing it so that the image shared has a semi-transparent watermark.
So far I can only share an image from URL using a share intent with the code below:
public void shareItem(String url) {
Picasso.with(getApplicationContext()).load(url).into(new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.putExtra(Intent.EXTRA_STREAM, getLocalBitmapUri(bitmap));
shareIntent.setType("image/png");
startActivity(Intent.createChooser(shareIntent, "Share with"));
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
}
public Uri getLocalBitmapUri(Bitmap bmp) {
Uri bmpUri = null;
try {
File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "share_image_" + System.currentTimeMillis() + ".png");
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;
}
you can use your uri as source in my code and create new uri for the output file(watermarked) to share via intent
Here is the calling code
String address = Environment.getExternalStorageDirectory().getAbsolutePath();
Bitmap source = BitmapFactory.decodeResource(getResources(), R.drawable.birds); // the original file is cuty.jpg i added in resources
Bitmap dest = addWatermark(source);
try {
dest.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(new File(address + "/output.jpg")));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
and this method will get the pretty job done.
public Bitmap addWatermark( Bitmap source) {
int width, height;
Canvas canvas;
Paint paint;
Bitmap bitmap, watermark;
Matrix matrix;
float scale;
RectF rectF;
width = source.getWidth();
height = source.getHeight();
// Create a new bitmap file and draw it on the canvas
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
canvas = new Canvas(bitmap);
canvas.drawBitmap(source, 0, 0, paint);
// now ready your watermark from the resources
watermark = BitmapFactory.decodeResource(getResources(), R.drawable.apple);
// scale / adjust height of your logo/watermark
// i am scaling it down to 30%
scale = (float) (((float) height * 0.30) / (float) watermark.getHeight());
// now create the matrix
matrix = new Matrix();
matrix.postScale(scale, scale);
// Determine the post-scaled size of the watermark
rectF = new RectF(0, 0, watermark.getWidth(), watermark.getHeight());
matrix.mapRect(rectF);
// below method will decide the position of the logo on the image
//for right bottom corner use below line
// matrix.postTranslate(width - rectF.width(), height - rectF.height());
// i am going to add it my logo at the top left corner
matrix.postTranslate(15,15);
// set alpha/opacity of paint which is going to draw watermark
paint.setAlpha(60);
// now draw the watermark on the canvas
canvas.drawBitmap(watermark, matrix, paint);
//cleaning up the memory
watermark.recycle();
// now return the watermarked image to the calling location
return bitmap;
}
here is the example image before
image after 60% alpha watermark applied at top left corner
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;
}
Here is the map page I have, which shows all the users of my App. Also the images(markers) are obtained from the URL given from my server. These markers has to put inside a Drawable(a circle like image as shown). I created a circle like Bitmap from the url using Canvas.
public Drawable showMe(String url)
{
Bitmap bitmap=null;
try {
URL newurl = new URL(url);
bitmap = BitmapFactory.decodeStream(newurl.openConnection().getInputStream());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bitmap=getBitmap(url);
Paint paint = new Paint();
paint.setFilterBitmap(true);
int targetWidth = 30;
int targetHeight = 30;
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight,Bitmap.Config.ARGB_8888);
RectF rectf = new RectF(0, 0, 30, 30);
Canvas canvas = new Canvas(targetBitmap);
Path path = new Path();
path.addRoundRect(rectf, targetWidth, targetHeight, Path.Direction.CW);
canvas.clipPath(path);
canvas.drawBitmap( bitmap, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()),
new Rect(0, 0, targetWidth, targetHeight), paint);
Matrix matrix = new Matrix();
matrix.postScale(1f, 1f);
Bitmap resizedBitmap = Bitmap.createBitmap(targetBitmap, 0, 0, 30, 30, matrix, true);
Bitmap bitmap_circle=mergeBitmaps(resizedBitmap);
BitmapDrawable bd = new BitmapDrawable(bitmap_circle);
return bd;
}
The above function will create the final drawable for the marker.Also the mergeBitmaps() function merge the both the resource drawable and the bit map together..
public Bitmap mergeBitmaps(Bitmap manBitmap){
try{
Bitmap markerBitmap = BitmapFactory.decodeResource( this.getResources(), R.drawable.circle_bg);
Bitmap bmOverlay = Bitmap.createBitmap(markerBitmap.getWidth(), markerBitmap.getHeight(), markerBitmap.getConfig());
Canvas canvas = new Canvas(bmOverlay);
Matrix matrix = new Matrix();
matrix.postScale(1f, 1f);
canvas.drawBitmap(markerBitmap, matrix, null);
canvas.drawBitmap(manBitmap, 5, 5, null);
return bmOverlay;
}
catch(Exception ex){
ex.printStackTrace();
return null;
}
}
But the problem is, this bitmap is not best fit inside the background Drawable in order to get a feeling that both together will give a single image.
Can anyone help me ?
change
canvas.drawBitmap(manBitmap, 5, 5, null);
to smtg like
canvas.drawBitmap(manBitmap, (markerBitmap.getWidth()-manbitmap.getWidth())/2,
(markerBitmap.getHeight()-manbitmap.getHeight())/2, null);
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
How do I cut out the middle area of the bitmap?
it's my sample code:
public void onPictureTaken(byte[] paramArrayOfByte, Camera paramCamera)
{
FileOutputStream fileOutputStream = null;
try {
File saveDir = new File("/sdcard/CameraExample/");
if (!saveDir.exists())
{
saveDir.mkdirs();
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 5;
Bitmap myImage = BitmapFactory.decodeByteArray(paramArrayOfByte, 0,paramArrayOfByte.length, options);
Bitmap bmpResult = Bitmap.createBitmap(myImage.getWidth(), myImage.getHeight(),Config.RGB_565);
int length = myImage.getHeight()*myImage.getWidth();
int[] pixels = new int[length];
myImage.getPixels(pixels, 0, myImage.getWidth(), 0,0, myImage.getWidth(), myImage.getHeight());
Bitmap TygolykovLOL = Bitmap.createBitmap(pixels, 0, myImage.getWidth(), myImage.getWidth(),myImage.getHeight(), Config.RGB_565);
Paint paint = new Paint();
Canvas myCanvas = new Canvas(bmpResult);
myCanvas.drawBitmap(TygolykovLOL, 0, 0, paint);
fileOutputStream = new FileOutputStream("/sdcard/CameraExample/" + "1ggggqqqqGj2.bmp");
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream );
bmpResult.compress(CompressFormat.PNG, 100, bos);
bos.flush();
bos.close();
You might want to use the other overload of createBitmap - it has x, y, width and height parameters which you could use to crop the middle portion of the bitmap into a new bitmap.
Something like this:
Bitmap cropped = Bitmap.createBitmap(sourceBitmap, 50, 50, sourceBitmap.getWidth() - 100, sourceBitmap.getHeight() - 100);
to clip out everything 50 pixels in from the edges.