How to add padding completely around a bitmap programmatically? - android

I'm trying to add padding to a bitmap programmatically however, when I add the padding to the top, it's removed from the bottom. When I add it to the bottom, it's removed from the top.
Adding padding to the top
Bitmap backgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap();
int padding = 60;
int positionLeft = 0;
int positionTop = 0;
Bitmap mainBitmap = Bitmap.createBitmap(
backgroundBitmap.getWidth(), //Adding top padding here
backgroundBitmap.getHeight() + padding,
Bitmap.Config.ARGB_8888
);
Canvas canvas = new Canvas(mainBitmap);
canvas.drawBitmap(
backgroundBitmap,
positionLeft + padding,
positionTop + padding,
null
);
Adding padding to the bottom removes the top padding
Bitmap backgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap();
int padding = 60;
int positionLeft = 0;
int positionTop = 0;
Bitmap mainBitmap = Bitmap.createBitmap(
backgroundBitmap.getWidth(),
backgroundBitmap.getHeight() + padding,
Bitmap.Config.ARGB_8888
);
Canvas canvas = new Canvas(mainBitmap);
canvas.drawBitmap(
backgroundBitmap,
positionLeft + padding,
positionTop, //Adding bottom padding here
null
);
Can't figure out
how can I add padding to all 4 sides to my backgroundBitmap bitmap?
Edit1:____________________________________________
I've also tried this solution:
https://stackoverflow.com/a/15525394/11110509
which adds a border to the bitmap, however it's only adding the border to the top and left. Doesn't include the bottom and right
private Bitmap addWhiteBorder(Bitmap bmp, int borderSize) {
Bitmap bmpWithBorder = Bitmap.createBitmap(bmp.getWidth() + borderSize * 2, bmp.getHeight() + borderSize * 2, bmp.getConfig());
Canvas canvas = new Canvas(bmpWithBorder);
canvas.drawColor(Color.BLUE);
canvas.drawBitmap(bmp, borderSize, borderSize, null);
return bmpWithBorder;
}
Bitmap backgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap();
int padding = 60;
int positionLeft = 0;
int positionTop = 0;
Bitmap mainBitmap = Bitmap.createBitmap(
backgroundBitmap.getWidth(),
backgroundBitmap.getHeight(),
Bitmap.Config.ARGB_8888
);
Canvas canvas = new Canvas(mainBitmap);
canvas.drawBitmap(
addWhiteBorder(backgroundBitmap, padding),
positionLeft,
positionTop,
null
);

This may or may not help you but don't pad the Bitmap, add it to a container in the view like a linearlayout and then pad the linearlayout . It should be a lot easier to deal with.
int left = (canvas.getWidth()-mainBitmap.getWidth())/2;
int top = (canvas.getHeight()-mainBitmap.getHeight())/2;
canvas.drawBitmap(mainBitmap, left, top, null);
This should get the the bitmap to the center in relation to the canvas.
I got it from here if you need more info How to align the canvas object to center of the screen?

The main issue was that I didn't have enough padding space in my main Bitmap
Bitmap backgroundBitmap = ((BitmapDrawable) backgroundDrawable).getBitmap();
Bitmap appLogoBitmap = ((BitmapDrawable) appLogoDrawable).getBitmap();
int padding = 60;
int positionLeft = 0;
int positionTop = 0;
Bitmap mainBitmap = Bitmap.createBitmap(
backgroundBitmap.getWidth() + (padding * 2), //Adding the * 2 helped display the padding
backgroundBitmap.getHeight() + (padding * 2),
Bitmap.Config.ARGB_8888
);
Canvas canvas = new Canvas(mainBitmap);
canvas.drawBitmap(
addWhiteBorder(backgroundBitmap, padding),
positionLeft,
positionTop,
null
);
And the function to add the padding:
private Bitmap addWhiteBorder(Bitmap bmp, int borderSize) {
Bitmap bmpWithBorder = Bitmap.createBitmap(bmp.getWidth() + borderSize * 2, bmp.getHeight() + borderSize * 2, bmp.getConfig());
Canvas canvas = new Canvas(bmpWithBorder);
canvas.drawColor(Color.parseColor("#63A4FF"));
canvas.drawBitmap(bmp, borderSize, borderSize, null);
return bmpWithBorder;
}

Related

Draw outline from image

I wanted to draw a contour around the picture by drawing and expanding a second picture in the Background, but I wasn't very successful, how can I draw a regular stroke?
The contour I drew:
The contour I want to draw:
My Code;
private Bitmap ContourBitmap() {
int strokeWidth = 8;
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower_icon);
Bitmap newStrokedBitmap = Bitmap.createBitmap(originalBitmap.getWidth() + 2 * strokeWidth,
originalBitmap.getHeight() + 2 * strokeWidth, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newStrokedBitmap);
float scaleX = (originalBitmap.getWidth() + 2.0f * strokeWidth) / originalBitmap.getWidth();
float scaleY = (originalBitmap.getHeight() + 2.0f * strokeWidth) / originalBitmap.getHeight();
Matrix matrix = new Matrix();
matrix.setScale(scaleX, scaleY);
canvas.drawBitmap(originalBitmap, matrix, null);
canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_ATOP); //Color.WHITE is stroke color
canvas.drawBitmap(originalBitmap, strokeWidth, strokeWidth, null);
}
I think you are on the right track...
Here is a strategy, instead of scaling just draw the same original picture a few times each time slightly offset, see sample below:
var canvas = document.getElementById('canvas')
var ctx = canvas.getContext('2d')
var img = new Image;
img.onload = draw;
img.src = "http://i.stack.imgur.com/UFBxY.png";
var s = 10, // thickness scale
x = 15, // final position
y = 15;
function draw() {
ctx.globalAlpha = 0.2
ctx.filter = 'brightness(0%)'
for (i = 0; i < 360; i++)
ctx.drawImage(img, x + Math.sin(i) * s, y + Math.cos(i) * s);
ctx.globalAlpha = 1
ctx.filter = 'none'
ctx.drawImage(img, x, y);
}
<canvas id=canvas width=350 height=600></canvas>
I applied a filter = 'brightness(0%)' but there are many more you can apply:
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter
I'm using HTML canvas but that same idea should "translate" nicely to an android canvas.

How to scale Canvas and draw thin border around the edge?

I have been struggling to get the preview of a PDF in the Android Print Framework to match the print output. However, I am able to get the output to match as a bitmap. However, if I scale the bitmap and put whitespace around the bitmap, the Print Framework crops out the whitespace. So, to prevent that from happening, I would like to draw a thin border around the edge of the entire Canvas.
This is the code that I have to scale the bitmap:
public static Bitmap captureScreen(View v) {
Bitmap screenshot = null;
Bitmap output = null;
try {
if (v != null) {
screenshot = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
int width = screenshot.getWidth();
int height = screenshot.getHeight();
int scaledWidth = (int) (width * 0.5);
int scaledHeight = (int) (height * 0.5);
output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Bitmap scaled = Bitmap.createScaledBitmap(screenshot, scaledWidth, scaledHeight, false);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
int distX = (width - scaledWidth) / 2;
int distY = (height - scaledHeight) / 2;
canvas.drawBitmap(scaled, distX, distY, paint);
v.draw(canvas);
}
} catch (Exception e) {
Log.d("ScreenShotActivity", "Failed to capture screenshot because:" + e.getMessage());
}
return output;
}
I would like to draw a thin black border around the entire canvas for I can prevent the whitespace from being cropped out by the Print Framework.
Well, you have the width and height of the canvas, just call Canvas.drawRect(0, 0, width - 1, height - 1, strokePaint)?

Overlay Shapes in XML Drawable

Is there a way to overlay a bitmap onto a shape in an XML drawable? I want to put an icon on top of an oval shape.
public static Bitmap overlayBitmapToCenter(Bitmap bitmap1, Bitmap bitmap2) {
int bitmap1Width = bitmap1.getWidth();
int bitmap1Height = bitmap1.getHeight();
int bitmap2Width = bitmap2.getWidth();
int bitmap2Height = bitmap2.getHeight();
float marginLeft = (float) (bitmap1Width * 0.5 - bitmap2Width * 0.5);
float marginTop = (float) (bitmap1Height * 0.5 - bitmap2Height * 0.5);
Bitmap overlayBitmap = Bitmap.createBitmap(bitmap1Width, bitmap1Height, bitmap1.getConfig());
Canvas canvas = new Canvas(overlayBitmap);
canvas.drawBitmap(bitmap1, new Matrix(), null);
canvas.drawBitmap(bitmap2, marginLeft, marginTop, null);
return overlayBitmap;
}

Android magnify view and draw as bitmap

I've a camera and from this I take a photo and save a bitmap. Overlayed to this, there's a view pager, with different layouts. When I take a photo, I want to save the current overlayed layout too.
The problem is that photo and layout are both saved, the layout fix correctly in the bitmap area, but it's smaller in respect as was in the preview camera. I need to magnify the layout (to look as it was before to the photo) and to save it in my bitmap.
Before to take photo:
After (it's ok that the button is still there, it's just a test):
My code:
Bitmap cameraBitmap = BitmapFactory.decodeByteArray
(data, 0, data.length);
int wid = cameraBitmap.getWidth();
int hgt = cameraBitmap.getHeight();
bitmap = Bitmap.createBitmap
(wid, hgt, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(cameraBitmap, 0f, 0f, null);
ViewPager pager = (ViewPager) main_activity.findViewById(R.id.pager);
ScreenSlidePagerAdapter a = (ScreenSlidePagerAdapter) pager.getAdapter();
ScreenSlidePageFragment currFrag = (ScreenSlidePageFragment) a.instantiateItem(pager, a.getFocusedPage());
View currView = currFrag.getView();
Rect rect = new Rect();
rect.set(0, 0, wid, hgt);
//Measure the view at the exact dimensions (otherwise the text won't center correctly)
int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);
int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);
currView.measure(widthSpec, heightSpec);
//Lay the view out at the rect width and height
currView.layout(0, 0, rect.width(), rect.height());
//Translate the Canvas into position and draw it
canvas.save();
canvas.translate(rect.left, rect.top);
currView.draw(canvas);
canvas.restore();
Why not create the bitmap with porportions. To do so, you need to create a Scalable Bitmap, and make the width like 1/4 of the screen and the height one fourth of the screen height.
To do so, first in the onCreate() method, also add in the following code to get the screenWidth and Height. -
metrics = getResources().getDisplayMetrics();
display = getWindowManager().getDefaultDisplay();
dpi = metrics.densityDpi;
size = new Point();
display.getSize(size);
screenWidth = size.x;
screenHeight = size.y;
To create a scalable bitmap use the following code, but remember to set the width and height values porportional such as the following --
public static int height = MainActivity.screenWidth* 4/10;
public static int width = MainActivity.screenWidth* 4/10;
bg = BitmapFactory.decodeResource(getResources(), R.drawable.bg);
if (width + heigt > 0) {
bg = Bitmap.createScaledBitmap(bg,
(width), (heigt),
false);
}
Also, to make sure the drawable images stay in quality, make sure to create seperate drawable folders, such as 'xxhdpi,and hdpi.'Refer to http://developer.android.com/guide/practices/screens_support.html. Hope that helps. Good luck.
I created a new bitmap with the view and I merged it with the previous bitmap, the result was good:
Bitmap cameraBitmap = BitmapFactory.decodeByteArray
(data, 0, data.length);
int wid = cameraBitmap.getWidth();
int hgt = cameraBitmap.getHeight();
bitmap = Bitmap.createBitmap
(wid, hgt, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawBitmap(cameraBitmap, 0f, 0f, null);
ViewPager pager = (ViewPager) main_activity.findViewById(R.id.pager);
ScreenSlidePagerAdapter a = (ScreenSlidePagerAdapter) pager.getAdapter();
ScreenSlidePageFragment currFrag = (ScreenSlidePageFragment) a.instantiateItem(pager, a.getFocusedPage());
View currView = currFrag.getView();
Bitmap viewBitmap = CustomUtil.loadBitmapFromView(currView);
viewBitmap = Bitmap.createScaledBitmap(viewBitmap, wid, wid, false);
canvas.drawBitmap(viewBitmap, 0f, (hgt-wid)/2 /* to center my square view in my rectangular original bitmap */, null);
An utility method:
public static Bitmap loadBitmapFromView(View view) {
int width = view.getWidth();
int height = view.getHeight();
int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
//Cause the view to re-layout
view.measure(measuredWidth, measuredHeight);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
//Create a bitmap backed Canvas to draw the view into
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
//Now that the view is laid out and we have a canvas, ask the view to draw itself into the canvas
view.draw(c);
return b;
}

How to take screenshot of visible area of horizontalscrollview in android?

I am working on an android app and I want to take screenshot of a visible area of horizontalscrollview. I am using below code for that :-
public Bitmap screenShot(View view) {
/*Rect rect = new Rect(0, 0,
mDiviceWidth , view.getHeight());*/
/*Rect rect = new Rect(view.getScrollX(), 0,
view.getScrollX() + mDiviceWidth , view.getHeight());*/
Rect scrollBounds = new Rect();
// view.getHitRect(scrollBounds);
// view.getDrawingRect(scrollBounds);
// view.getLocalVisibleRect(scrollBounds);
// view.getGlobalVisibleRect(scrollBounds);
view.getWindowVisibleDisplayFrame(scrollBounds);
Log.e("X Scrolled", ""+view.getScrollX());
Log.e("left", ""+scrollBounds.left);
Log.e("right", ""+scrollBounds.right);
Log.e("top", ""+scrollBounds.top);
Log.e("bottom", ""+scrollBounds.bottom);
/*view.setDrawingCacheEnabled(true);
Bitmap bitmap = view.getDrawingCache();*/
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Config.ARGB_8888);
/*float left,right,top,bottom;
left = view.getLeft();
right = mDiviceWidth;
top = 0;
bottom = view.getHeight();*/
Canvas canvas = new Canvas(bitmap);
// canvas.clipRect(left, top,
// right , bottom);
canvas.clipRect(scrollBounds);
view.draw(canvas);
// view.setDrawingCacheEnabled(false);
return bitmap;
}
Above code is taking the screenshot but returning wrong area. Some times it captures visible area but sometimes it captures the random area which is not visible or partial visible. I have already used
// view.getHitRect(scrollBounds);
// view.getDrawingRect(scrollBounds);
// view.getLocalVisibleRect(scrollBounds);
// view.getGlobalVisibleRect(scrollBounds);
methods but not getting the perfect result.
So please help me to resolve this issue.
Use this function:
private static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay().getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height - statusBarHeight);
view.destroyDrawingCache();
return b;
}

Categories

Resources