I have a requirement where I will be having a background Image and one mask Image. Lets say the background Image is of Motorcycle and the mask will be used to hide the registration number. So the mask will be movable and also resize-able. Finally the combined Image will be generated with background image and Image mask. How we can achieve this ?
public Bitmap drawFacesOnBitmap(Context gContext, Bitmap bitmap) {
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if(bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialised Paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.GREEN);
// draw text to the Canvas center
Log.d("BITMAP DIMENS****", "bitmapWidth:"+bitmap.getWidth()+" & bitmapHeight:"+bitmap.getHeight());
android.graphics.Rect r = new android.graphics.Rect();
r.left = 200;
r.top = 200;
r.right = 400;
r.bottom = 400;
canvas.drawRect(r, paint);
return bitmap;
}
You can use this code to draw a rectangle on a bitmap. Edit it to meet your needs.
Related
I've got a bitmap displayed in an ImageView, and I want to be able to make a certain percentage of the image black and white, and have the other part retain it's color. For example, if 60% is the target percentage, the image would look like this: . Thanks.
I've got a bitmap displayed in an ImageView, and I want to be able to
make a certain percentage of the image black and white, and have the
other part retain it's color. For example, if 60% is the target
percentage.
It seems (from your image) you mean monochrome (i.e. greyscale), not black and white.
Something like this should do it (tested o.k.):
void doIt(ImageView image)
{
//get bitmap from your ImageView (image)
Bitmap originalBitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
int height = originalBitmap.getHeight();
int fortyPercentHeight = (int) Math.floor(height * 40.0 / 100.0);
//create a bitmap of the top 40% of image height that we will make black and white
Bitmap croppedBitmap = Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth() , fortyPercentHeight );
//make it monochrome
Bitmap blackAndWhiteBitmap = monoChrome(croppedBitmap);
//copy the monochrome bmp (blackAndWhiteBitmap) to the original bmp (originalBitmap)
originalBitmap = overlay(originalBitmap, blackAndWhiteBitmap);
//set imageview to new bitmap
image.setImageBitmap(originalBitmap );
}
Bitmap monoChrome(Bitmap bitmap)
{
Bitmap bmpMonochrome = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmpMonochrome);
ColorMatrix ma = new ColorMatrix();
ma.setSaturation(0);
Paint paint = new Paint();
paint.setColorFilter(new ColorMatrixColorFilter(ma));
canvas.drawBitmap(bitmap, 0, 0, paint);
return bmpMonochrome;
}
Bitmap overlay(Bitmap bmp1, Bitmap bmp2)
{
Bitmap bmp3 = bmp1.copy(Bitmap.Config.ARGB_8888,true);//mutable copy
Canvas canvas = new Canvas(bmp3 );
canvas.drawBitmap(bmp2, new Matrix(), null);
return bmp3 ;
}
My app uses geojson to draw features on map. To draw feature:
for (GeoJsonFeature f : new GeoJsonLayer(googleMap, new JSONObject(geojson)).getFeatures())
{
f.setPointStyle(getPointStyle(text,status);
layer.addFeature(f);
}
layer.addLayerToMap();
To generate point (marker) style and set icon:
GeoJsonPointStyle markerStyle = new GeoJsonPointStyle();
int[] markers = {R.drawable.marker0,R.drawable.marker1,R.drawable.marker2,R.drawable.marker3,R.drawable.marker4};
bmp = Utils.drawTextToBitmap(getContext(), markers[status], icon);
markerStyle.setIcon(highlighted ? BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN):BitmapDescriptorFactory.fromBitmap(bmp));
drawTextToBitmap just generates bitmap with text on it:
public static Bitmap drawTextToBitmap(Context gContext, int gResId, String gText)
{
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
if (bitmapConfig == null)
{
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
paint.setTextSize((int) (18 * scale));
Typeface tf = Typeface.createFromAsset(gContext.getAssets(), "fonts/fontawesome.ttf");
paint.setTypeface(Typeface.create(tf, Typeface.BOLD));
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
Rect bounds = new Rect();
paint.getTextBounds(gText, 0, gText.length(), bounds);
int x = (bitmap.getWidth() - bounds.width()) / 2;
int y = (bitmap.getHeight() + bounds.height()) / 2 -8;
canvas.drawText(gText, x, y, paint);
return bitmap;
}
My problem is that on some phones (not on every phone) this approach causes huge memory leak if there is big amount of markes to draw on map. Problem does not exists if I use static marker drawable from resources, but I need dynamic bitmap to add text on it.
Do you have any idea about memory leak cause? It seems map holds bitmap reference so it prevents garbage from disposing it. Even if map fragment is destroyed, map resources will be never released, so after displaying map few times, app stops working due to OutOfMemory exception.
I have a requirement, like drawing something in canvas and saving it to a larger image. As of now whatever I draw inside onDraw() method and save, it gives device provided image/canvas size, say something around 538(w)/852(h). I need image of almost double size, around 1000(w)/1500(h) without losing resolution. Any sample code, reference link would help definitely. Thanks in advance.
One way is to create Bitmap of desired size and draw on it using canvas:
int w = 1000, h = 1500;
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bmp = Bitmap.createBitmap(w, h, conf);
Canvas canvas = new Canvas(bmp);
Finally you will have you bmp with your drawing and necessary dimentions.
EDIT::
#Override
protected void onDraw(Canvas canvas) {
int w = 1000, h = 1500;
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bmp = Bitmap.createBitmap(w, h, conf);
Canvas mycanvas = new Canvas(bmp);
super.onDraw(mycanvas);
...
}
First get bitmap of your view using the function getDrawingCache(), then scale the bitmap as per your requirements.
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
//bitmap = bitmap.createScaledBitmap(..as your requirements..);
EDIT
You are saying that you want image in higher quality. You can't simply get a higher quality image from a lower quality image. However you can apply bitmap filtering to get slightly better quality.
Bitmap bitmap = getDrawingCache();
Bitmap output = Bitmap.createBitmap(/*width, height, bla bla bla*/);
Canvas canvas = new Canvas(output);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
Rect srcRect = new Rect(0,0,bitmap.getWidth(), bitmap.getHeight());
Rect destRect = new Rect(0,0,output.getWidth(), output.getHeight());
canvas.drawBitmap(bitmap, srcRect, destRect, paint);
I have the coordinates and I would like to draw a line or rectangular on a jpg image which is saved in my android device and then save the new file.
Is it possible? I am trying to us ImageIO but it isn't available in android or something goes wrong and it isn't acceptable?
Any idea or code?
This is how I was able to draw a green box on an existing JPEG.
Bitmap workingBitmap = BitmapFactory.decodeFile( mFullFilePath );
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
// bitmap needs to be mutable
Canvas tmpCanvas = new Canvas(mutableBitmap);
// setup paint parameters
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth( 5 );
paint.setColor(Color.GREEN);
// Rect object was passed; use below to test
// Rect rect = new Rect( 0, 0, 10, 10 );
tmpCanvas.drawRect(rect, paint);
// write the updated file out as a JPG
writeExternalToCache( mutableBitmap, mFullFilePath );
see also:
https://stackoverflow.com/a/13119762/3474698
https://stackoverflow.com/a/8801391/3474698
I was wondering, how do I merge/join Android canvases. In the code below I have cnv_left which contains a left part of a button. cnv_center contains the center part. And cnv_text contains text.
What I need is to merge them all in cnv_joined , so that
cnv_left would go first.
then cnv_center.
cnv_text would be in center of cnv_center.
and a flipped cnv_left would be the last.
Here's my code so far:
public void drawButt()
{
float buttonScale = 1.0f; /// general button scale ratio
float buttonScaleCnt = 6.0f; /// button's center part stretch ratio
LinearLayout LinLay = (LinearLayout)findViewById(R.id.linearLayout1);
ImageView iv1 = new ImageView(this);
Bitmap bit_left = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas cnv_left = new Canvas(bit_left);
cnv_left.scale(buttonScale,buttonScale);
SVG svg_left = SVGParser.getSVGFromResource(getResources(), R.raw.btleft);
Picture picture_left = svg_left.getPicture();
picture_left.draw(cnv_left);
Bitmap bit_center = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas cnv_center = new Canvas(bit_center);
cnv_center.scale(buttonScaleCnt, buttonScale);
SVG svg_center = SVGParser.getSVGFromResource(getResources(), R.raw.btcnt);
Picture picture_cnt = svg_center.getPicture();
picture_cnt.draw(cnv_center);
Bitmap bit_text = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
Canvas cnv_text = new Canvas(bit_text);
cnv_text.scale(buttonScale, buttonScale);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setColor(Color.WHITE); paint.setTextSize(20);
cnv_text.drawText("R", 2, 30, paint);
Bitmap bit_joined = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888);
Canvas cnv_joined = new Canvas(bit_joined);
/// somehow need to somehow join the above canvases into this cnv_joined...
iv1.setImageBitmap(bit_joined);
iv1.setPadding(5, 5, 5, 5);
LinLay.addView(iv1);
}
Any ideas? Oh, and one more thing, when I create empty bitmaps for my canvas ( Bitmap.createBitmap(100, 100... ), does it matter what size I give them? If yes, where should I get the correct sizes for them?
Thanks!
Size of Bitmaps matter. If you do Picture.draw to canvas smaller than Picture, image will be cropped to size of bitmap.
Call SVG.getBounds to get bounds and put them in Bitmap constructor.
To join Bitmaps together you have to draw bit_left, bit_center and bit_text on cnv_joined using drawBitmap.
Better way will be to draw SVGs and text directly on cnv_joined.