I am trying to make my game a bit easier on the phone, so I am trying to figure out a way to print a bunch of bitmaps onto another big one, so I can just do it once, rather than every time the screen is redrawn. So, is there any way to do this? I know there is a way to print everything that is printed to the canvas to a bitmap, but I can't seem to get that to work. If that is the only way can someone explain how to do that? Thanks in advance.
Here is something I tried, but it didn't work out so well
Bitmap background;
Canvas canvas;
private void methodName() {
background = Bitmap.createBitmap(width, height, someKindOfConfigThing);
canvas = new Canvas(background);
canvas.drawBitmap(blahblah);
}
What you would do is to create the main bitmap, attach that to a canvas to which you can draw.
Bitmap bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
Canvas c = new Canvas(bitmap);
You can draw (parts of) bitmaps to this canvas using
c.drawBitmap(anotherBitmap, transformMatrix, paint);
To attach the main bitmap to the view you would create a new ImageView, call setImageBitmap passing your main bitmap and set it as the current contentview using setContentView.
If you want to combine multiple bitmaps to another big one and reuse that, you already on the right way! Show us what you have done and tell us what the result is. I guess we can help you :)
[update] it should be possible to save this new bitmap to disc or store it temporarily as a variable:
private void methodName() {
background = Bitmap.createBitmap(width, height, someKindOfConfigThing);
canvas = new Canvas(background);
// drawing on the canvas should change the bitmap "background" too
canvas.drawBitmap(blahblah);
FileOutputStream fos = null;
try {
fos = new FileOutputStream("/path/to/image.png");
background.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (Exception e) {
// catching...
}
}
Related
I am working on application that allows users to shade a portion of bitmap when the swipe on it. Then when he finishes swiping I call a method to crop that portion of bitmap and perform some function(but cropped bitmap is not saved anywhere so doubt there is any problem here). On click on imageView I reset the bitmap with original bitmap. There is also a functionality to rotate the bitmap.I have two bitmap objects bill(user actually swipes on it) and billOrg(original bitmap as it is). Below are the methods.
private void drawShade(float left,float top,float right,float bottom){
//this method draws shade on bitmap. Coordinates are sent from onTouchEvent
TAG = "drawShade";
//parseTouchPointsString();
Bitmap tempBitmap = Bitmap.createBitmap(bill.getWidth(), bill.getHeight(), Bitmap.Config.RGB_565);
Log.d(TAG,"bill:"+bill.isMutable()+"tempBit:"+tempBitmap.isMutable()+"");
Canvas tempCanvas = new Canvas(tempBitmap);
tempCanvas.drawBitmap(bill,0,0,null);
tempCanvas.drawRoundRect(new RectF(left,top,right,bottom), 10, 10, shadePaint);
imgView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap));
if(fingerUp) {
Log.e("fingerUp",fingerUp+"");
bill = tempBitmap;
}
Log.d(TAG,"shade drawn at:"+left+","+top+","+right+","+bottom);
}
Here is method to rotate bitmap :
public void rotateImage(View v){
TAG = "rotateImage";
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(bill , 0, 0, bill.getWidth(), bill.getHeight(), matrix, true);
bill = rotatedBitmap.copy(rotatedBitmap.getConfig(),true);
createScaledBitmap();
billOrg = bill.copy(rotatedBitmap.getConfig(),true);//bill.copy(bill.getConfig(),false);
setImage(bill);
rl.invalidate();
}
Method to reset bitmap on click :
private void resetImageView(boolean saveShade){
//the boolean var here tell whether to keep the shaded portion after reset or not
if(!saveShade) { //app crashes in this if block although I have try-catch.
try {
Canvas canvas = new Canvas(bill);
Log.e("resetImageView", "billOrg:" + billOrg.isMutable() + ",bill:" + bill.isMutable()); //returns true for both bitmap objects
canvas.drawBitmap(billOrg, 0, 0, null);
touchBounds = "";
tv_res.setText("");
rl.invalidate();
setImage(bill);
}catch(Exception ex){
Log.e("resetImage",ex.getMessage());
}
}else{
Canvas canvas = new Canvas(bill);
canvas.drawBitmap(bill, 0, 0, null);
touchBounds = "";
tv_res.setText("");
rl.invalidate();
setImage(bill);
}
}
All is fine except when user first swipes the image --> then rotates the image --> then clicks on bitmap.
All I get is this error: jni_helper.cc:110 Bitmap is of the wrong format: 4. No other exceptions.
As per my knowledge bitmaps usually throw errors if we try to modify a bitmap object which is immutable but I have made it mutable in all places. It prints mutable in logs too. I guess I am doing something wrong while modifying the bitmaps. I know might be confusing for you. I don't know how well I have explained. If you need any clarity kindly ask. I need some help.
Ok so I found out what was causing the problem.
Bitmap tempBitmap = Bitmap.createBitmap(bill.getWidth(), bill.getHeight(), Bitmap.Config.RGB_565);
In the drawShade() method was culprit. I changed the "Bitmap.Config.RGB_565" to bill.getConfig() and it was fixed.
I want to take a picture of a view in Activity and share this picture.
First I use this method :
private Bitmap getShareViewShot() {
this.setDrawingCacheEnabled(true);
this.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(this.getDrawingCache(), 0, mSharePageRoot.getTop(), this.getWidth(), mSharePageRoot.getBottom());
this.setDrawingCacheEnabled(false);
return bitmap;
}
But if the view is in a ScrollView and the view has scrolled outside the screen, this method can't get a whole picture of this view.
So I change this method to below :
private Bitmap getShareViewShot() {
Bitmap bitmap = Bitmap.createBitmap(mSharePageRoot.getWidth(), mSharePageRoot.getHeight(),
Bitmap.Config.ARGB_8888);
mSharePageRoot.layout(0, 0, mSharePageRoot.getLayoutParams().width, mSharePageRoot.getLayoutParams().height);
final Canvas canvas = new Canvas(bitmap);
mSharePageRoot.draw(canvas);
return bitmap;
}
But another question comes: this view has no backgroud, so the picture I get has a black backgroud.In my code ,the Activity have a network image as the backgroud, so this means this method can't get the backgroud of the activity.
Please forgive me for my bad English.
Is there any other method ? thanks.
Yes, there is another method. There is a library by google called ASL(Android screenshot library). It's pretty simple.
https://code.google.com/archive/p/android-screenshot-library/wikis/DeveloperGuide.wiki
You can draw background by canvas, like this:
private Bitmap getShareViewShot() {
Bitmap bitmap = Bitmap.createBitmap(mSharePageRoot.getWidth(), mSharePageRoot.getHeight(),
Bitmap.Config.ARGB_8888);
mSharePageRoot.layout(0, 0, mSharePageRoot.getLayoutParams().width, mSharePageRoot.getLayoutParams().height);
final Canvas canvas = new Canvas(bitmap);
// the bitmap will have a white background
canvas.drawColor(0xffffffff);
mSharePageRoot.draw(canvas);
return bitmap;
}
I am working on a project in which I have created a custom view with transparent background. Now I want to create an image of this view. I am using the below code to save and create an image from bitmap, but the generated image has black background and not transparent. I want transparent background. How can I achieve this?
view = suraVersesFragment.getMyView();
view.setBackgroundColor(Color.TRANSPARENT);
Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
view.draw(c);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.png");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
For receiving a non scaled bitmap of a view you can call this method after you enabled the drawing cache
view.getDrawingCache()
the api tells this about the method:
Returns the bitmap in which this view drawing is cached. The returned bitmap is null when caching is disabled. If caching is enabled and the cache is not ready, this method will create it. Calling draw(android.graphics.Canvas) will not draw from the cache when the cache is enabled. To benefit from the cache, you must request the drawing cache by calling this method and draw it on screen if the returned bitmap is not null.
Note about auto scaling in compatibility mode: When auto scaling is not enabled, this method will create a bitmap of the same size as this view. Because this bitmap will be drawn scaled by the parent ViewGroup, the result on screen might show scaling artifacts. To avoid such artifacts, you should call this method by setting the auto scaling to true. Doing so, however, will generate a bitmap of a different size than the view. This implies that your application must be able to handle this size.
you also can set the background's color
view.setDrawingCacheBackgroundColor(Color.XY)
you can look this also up here:
http://developer.android.com/reference/android/view/View.html#getDrawingCache(boolean)
http://developer.android.com/reference/android/view/View.html#getDrawingCache()
http://developer.android.com/reference/android/view/View.html#setDrawingCacheBackgroundColor(int)
Hey Hi Try this for transparent
Bitmap bitmap= Bitmap.createBitmap(255, 255, Bitmap.Config.ARGB_8888);
after that try this line (A is alpha value interval is 0-255 and 0 is fully transparent).
bitmap.eraseColor(Color.argb(AAA,RRR,GGG,BBB));
Check This
i'm trying to draw a Bitmap but only with a selected area from the original Bitmap or Imageview. The requirement is that the final picture must show only 1/3 from the top of the original Bitmap. I attach a draft. I suppose that i should use canvas, but i do not know exactly how it works.
Thanks in advance!!
Bitmap getTheReducedBitmap(Bitmap fullLengthBitnap)
{
Bitmap backDrop=Bitmap.createBitmap(fullLengthBitnap.getWidth(), fullLengthBitnap.getHeight()/3, Bitmap.Config.RGB_565);
Canvas can = new Canvas(backDrop);
can.drawBitmap(fullLengthBitnap, 0, 0, null);
return backDrop;
}
This is the documentation for the method you should use.
private void draw(Canvas c, Bitmap bmp){
Rect r=new Rect(0,0,bmp.width,bmp.height/3);
Rect drawR=new Rect(0,0,c.width,c.height/3);
c.drawBitmap(bmp,r,drawR,null);
}
or as a one liner:
c.drawBitmap(bmp,new Rect(0,0,bmp.width,bmp.height/3),new Rect(0,0,c.width,c.height/3),null);
It allows you to specify where on the canvas you want to draw it too, and where you want the segment to be from.
#Eu.Dr. 's answer would not work if you wanted to draw anything else on the canvas below it.
val newBitmap=Bimtap
.createBitmap(your_view.width,your_view.height,Bitmap.Config.ALPHA_8)
//note: for tablet mode your_view.width,height will increase drastically so
//you might want
//to fix the size of drawing area for optimization
//ALPHA_8 each pixel requires 1 byte of memory.
//RGB_565 Each pixel is stored on 2 bytes
//ARGB_8888 Each pixel is stored on 4 bytes
//after this you can further apply the compress like
[Refer more from google][1]
val stream = ByteArrayOutputStream();
newBitmap.compress(Bitmap.CompressFormat.PNG, 80, stream);
val byteArray = stream.toByteArray(); // convert drawing photo to byte array
// save it in your internal storage.
val storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES
+"attendance_sheet.png");
try{
val fo = FileOutputStream(storageDir);
fo.write(byteArray);
fo.flush();
fo.close();
}catch(Exception ex){
}
I'm drawing a bitmap in a canvas and I want to have the result in a new bitmap, but I still have a black screen as result.
This is my code, part of the onDraw(Canvas canvas) method:
if (bitmapTemplate == null) {
canvasBis = new Canvas();
bitmapTemplate = Bitmap.createBitmap(canvas.getWidth()+30,canvas.getHeight(),Bitmap.Config.ARGB_8888);
drawZones(canvasBis,bitmapTemplate);
}
bitmapRes = Bitmap.createBitmap(canvas.getWidth()+30,canvas.getHeight(),Bitmap.Config.ARGB_8888);
canvas.setBitmap(bitmapRes);
canvas.drawBitmap(bitmapTemplate, matrix, null);
My goal is to have a new bitmap (bitmapRes) by applying a matrix on an existing bitmap (bitmapTemplate). With this code I always have a black screen, but when I remove the line canvas.setBitmap(bitmapRes), I have a result but not in a new bitmap. Any ideas please? Maybe transparency? Thanks in advance.
drawZones draws some zones in bitmapTemplate.
You should try using the Canvas(Bitmap) constructor instead of the empty constructor. This sets the bitmap to the canvas for you.