Setting a bitmap using RemoteView not working - android

Im writing a widget and I need to download and set a bitmap on the layout. Everything I've tried doesn't seem to work.
I've created a test bitmap now to set on the view, [update] this works.
Bitmap.Config config = Bitmap.Config.ARGB_8888;
Bitmap bitmap = Bitmap.createBitmap(imageActiveWidth, imageHeight, config);
Canvas canvas = new Canvas(bitmap); // Load the Bitmap to the Canvas
Paint paint = new Paint();
paint.setColor(0xFFFFCCFF);
canvas.drawRect(0, 0, imageActiveWidth, imageHeight, paint);
views.setImageViewBitmap(resId, bitmap);
using a resource file does work:
Bitmap placeholderBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.placeholder_medium);
views.setImageViewBitmap(imageSlotId, placeholderBitmap);
However using a downloaded bitmap does not seem work.
(after async task has downloaded bitmap, I have a method setBitmap which is one line:
views.setImageViewBitmap(resId, proxy);
Result - screen is just white, no bitmap
I'm really stumped on how to get this to work, because I need to be able to download bitmaps and set them.

Found a solution. I think its related to this bug:
http://code.google.com/p/android/issues/detail?id=8489
Solved by changing by setBitmap method to the following:
private void setBitmap(RemoteViews views, int resId, Bitmap bitmap){
Bitmap proxy = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(proxy);
c.drawBitmap(bitmap, new Matrix(), null);
views.setImageViewBitmap(resId, proxy);
}
And I needed to call:
AppWidgetManager.getInstance(context).updateAppWidget(appWidgetId, views);
AFTER the bitmaps had been set.
For some reason this wasn't working when I came back to it. My view was an AdapterViewFlipper, so i used the above method with a call to widgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.content); which caused the bitmaps to render.

Related

Android Drawing text onto a bitmap

I'm trying to write some text across a bitmap in Android. I've followed several guides and attempted several different code variations but I either get something obscure, a blank screen or the unaltered bitmap. This is the basic idea of what I've been playing around with.
public Bitmap writeOnDrawable(Context gContext, String path, String text) {
Bitmap bitmap = BitmapFactory.decodeFile(path);
Bitmap bmOverlay = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(bmOverlay);
Paint paint = new Paint();
paint.setColor(Color.CYAN);
paint.setTextSize(20);
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
canvas.drawBitmap(bitmap, 0, 0, null);
canvas.drawPoint(30, 50, paint);
canvas.drawText("Text", 33, 53, paint);
return bmOverlay;
}
I pass this function the variables and then use the returned bitmap by turning it into a BitmapDrawable and making it a background of a layout. This particular version of the function returns only my initial, unaltered bitmap with no "Text" text across it.
I've attempted variations such as copying the original image:
Bitmap drawableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Drawing the original image onto the canvas:
canvas.drawBitmap(drawableBitmap, screenHeight, screenWidth, paint);
I solved the problem using android-maps-util library.
add compile 'com.google.maps.android:android-maps-utils:0.4' dependency to your gradle file.
Use IconGenerator to create bitmap with text and use it in your BitmapDescriptor to create marker on your map.

Cannot draw on bitmap loaded canvas

I am trying to create an image save and retrieve feature in android. The code I have for creating a jpg file from canvas is as below
Bitmap bitmap = Bitmap.createBitmap( view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
I am trying to read the jpg file and create image on canvas using
Bitmap bMap = BitmapFactory.decodeStream(buf);
Bitmap workingBitmap = Bitmap.createBitmap(bMap);
Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
view.mybitmap = mutableBitmap;
view.onDraw(view.Canvas);
The code I have in onDraw is
canvas.drawBitmap(view.mybitmap, 0, 0, view.myPaint);
This draws the bitmap on canvas correctly from the stored jpg file but I am not able to draw anything on the canvas after that. Has it loaded a immutable bitmap image on canvas which I am not able to edit?
Any help will be appreciated! Thanks!
You shouldn't need to be calling the ondraw method directly like you are doing currently. For a custom view class all you should need to be calling is view.invalidate(); This will auto call the ondraw method and re-draw the canvas. You will probably need to update the logic in your ondraw method to handle the cases where you want to draw additional things on the canvas.

Android: onDraw is too slow

I'm building a game using Android 2.2. The main game Activity uses a custom SurfaceView:
class GameView extends SurfaceView
From what I understand, the onDraw() method requires its own Thread to be executed. That in mind, I am planning to add a background image in onDraw():
canvas.drawBitmap(wallpaper, 0, 0, paint);
paint = new Paint();
But when I execute the game, it becomes very slow. If I comment out the new Paint() line, the game speeds up.
Is there something I am doing wrong, or is there a solution to my problem? For example, is there a way to reduce the number of calls to onDraw()? Or add an XML attribute to my custom SurfaceView class?
Here's the code how I load the drawable images.
public Bitmap loadBitmap(String image) {
Bitmap bitmap = null;
try {
int id = R.drawable.class.getField(image).getInt(new Integer(0));
bitmap = BitmapFactory.decodeResource(context.getResources(), id);
// bitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.RGB_565);
} catch(Exception ex) {
Log.e("loadBitmap", ex.getMessage());
}
return bitmap;
}
Here's the code of the onDraw method.
Unfortunately, I can't post everything.
paint.setColor(Color.BLACK);
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
canvas.drawBitmap(gameLevel.getBitmap(), 0, 0, paint);
// draw object(1) 320x25
// draw object(5) 50x50 each
// draw object(n) 15x15 each, estimate
// draw object(n) 50x50 each
// collision check, draw hit tile on the image sheet
// draw game information using canvas.drawText()
timeLine++;
Thanks in advance!
If the problem is only the "paint = new Paint();" line, why don't you create the Paint object only once? When the class is first created and make it a Class variable. Then just use the object everytime you want.
You could try to load the background as RGB_565 instead of ARGB_8888 in case you haven't already. Otherwise there is not much you can do except switching to OpenGL
EDIT:
Options options = new Options();
options.inDither = false;
options.inJustDecodeBounds = false;
options.inSampleSize = 1;
options.mCancel = false;
options.inPreferredConfig = Config.RGB_565;
bitmap = BitmapFactory.decodeResource(context.getResources(), id, options);
If that doesn't help other reasons may be:
You drawing code is wrong
You scale the background when you draw it
You run it on an emulator

Android merge two images

I want to merge two images and then save them on the Android SDCard.One is from the camera and one from the resources folder. The problem is that i get this error: Caused by: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor. Thanks.
Bitmap bottomImage = BitmapFactory.decodeResource(getResources(),R.drawable.blink);
Bitmap topImage = (Bitmap) data.getExtras().get("data");
// As described by Steve Pomeroy in a previous comment,
// use the canvas to combine them.
// Start with the first in the constructor..
Canvas comboImage = new Canvas(bottomImage);
// Then draw the second on top of that
comboImage.drawBitmap(topImage, 0f, 0f, null);
// bottomImage is now a composite of the two.
// To write the file out to the SDCard:
OutputStream os = null;
try {
os = new FileOutputStream("/sdcard/DCIM/Camera/" + "myNewFileName.png");
bottomImage.compress(CompressFormat.PNG, 50, os);
//Bitmap image.compress(CompressFormat.PNG, 50, os);
} catch(IOException e) {
Log.v("error saving","error saving");
e.printStackTrace();
}
Managed to fix it by simply doing this change:
int w = bottomImage.getWidth();
int h = bottomImage.getHeight();
Bitmap new_image = Bitmap.createBitmap(w, h ,bottomImage.getConfig());
The problem now is that it doesn't saves the image. Do you know why?
This will help you =)
Edit: (embed answer from link)
the only static "constructor" for Bitmap returning a mutable one is:
(Class: Bitmap) public static Bitmap createBitmap(int width, int
height, boolean hasAlpha)
Returns: a mutable bitmap with the specified width and height.
So you could work with getPixels/setPixels or like this:
Bitmap bitmapResult = bm.createBitmap(widthOfOld, heightOfOld, hasAlpha);
Canvas c = new Canvas();
c.setDevice(bitmapResult); // drawXY will result on that Bitmap
c.drawBitmap(bitmapOld, left, top, paint);
how to get the drawable from Bitmap: by using the BitmapDrawable-Subclass which extends Drawable, like this:
Bitmap myBitmap = BitmapFactory.decode(path);
Drawable bd = new BitmapDrawable(myBitmap);
The bitmap you are retrieving is immutable, meaning it can't be modified. Although it doesn't specify on the Canvas page that the constructor needs a mutable bitmap, it does.
To create a mutable bitmap, you can use this method.

error with setPixels

i am trying to edit images. but i am getting errors with setPixels.
picw = pic.getWidth();
pich = pic.getHeight();
picsize = picw*pich;
int[] pix = new int [picsize];
pic.getPixels(pix, 0, picw, 0, 0, picw, pich);
pic.setPixels(pix,0,pic.getWidth(),0,0,pic.getWidth(),pic.getHeight());
but i am getting illegal state exception with setPixels
Caused by: java.lang.IllegalStateException
at android.graphics.Bitmap.setPixels(Bitmap.java:878)
at com.sandyapps.testapp.testapp.onCreate(testapp.java:66)
I think your Bitmap is not mutable (see setPixel()'s documentation).
If so, create a mutable copy of this Bitmap (using Bitmap.copy(Bitmap.Config config, boolean isMutable) as an example) and work on this one.
It's simple, just use the following command to change it to a mutable Bitmap:
myBitmap = myBitmap.copy( Bitmap.Config.ARGB_8888 , true);
Now the Bitmap myBitmap is replaced by the same Bitmap but this time is mutable
You can also choose another way of storing Pixels (ARGB_8888 etc..):
https://developer.android.com/reference/android/graphics/Bitmap.Config.html
Most probably your pic is immutable. By default, any bitmap created from drawable would be immutable.
If you need to modify an existing bitmap, you should do following:
// Create a bitmap of the same size
Bitmap newBmp = Bitmap.createBitmap(pic.getWidth(), pic.getHeight(), Config.ARGB);
// Create a canvas for new bitmap
Canvas c = new Canvas(newBmp);
// Draw your old bitmap on it.
c.drawBitmap(pic, 0, 0, new Paint());
I had the same problem. Use to fix it:
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inMutable = true;
Bitmap bitmap = BitmapFactory.decodeResource( getResources(), R.drawable.my_bitmap, opt );
I was facing this problem and finally fixed after long time.
public static void filterApply(Filter filter){
Bitmap bitmcopy = PhotoModel.getInstance().getPhotoCopyBitmap();
//custom scalling is important to apply filter otherwise it will not apply on image
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmcopy, bitmcopy.getWidth()-1, bitmcopy.getHeight()-1, false);
filter.processFilter(scaledBitmap);
filterImage.setImageBitmap(scaledBitmap);
}

Categories

Resources