I would like to show a picture (for example a house) from its various parts like its door, window, roof etc (different images of various part saved in asset folder). i am totally in dark from where and how to start to make this. If any idea or any library please help.
you can load the images from resource on to a bitmap like so:
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.place_drawable_name_here)
then use a custom view, on its onDraw method you can draw all you bitmaps one by one, the door,roof etc... so it will eventually look like a house.
public class MyCustomView extends View{
#Override
protected void onDraw(Canvas canvas) {
...
canvas.drawBitmap(bmp, 0, 0, paint);
}
}
this is of course not a fully working code but it should give you pretty good idea of how you could implement what you wanted.
Related
i am implementing a custom launcher in Android, displaying 3rd party apps using ActivityViews.
I want to clip the content of these ActivityViews to a custom shape (other than Circle, Rectangle, RoundedRectangle, Ring...).
I already tried to call clipPath/drawPath on the dispatchDraw canvas of a parent viewgroup element which works fine for all children except the ActivityView. Even the ActivityView itself and its referenced SurfaceView seem to be clipped according to my given path (if i add a solid color for testing). But the rendered content remains unchanged. Manipulating the SurfaceView canvas (which you receive by calling getHolder().lockCanvas()) doesnt have any effect, too.
I think this has something to do with the virtualdisplay and/or various SurfaceControls which are used by the ActivityView, but i dont have any clue how to set clipping areas/paths for those classes.
Does anyone have an idea how to solve this?
Hint: i cannot paint over the ActivityViews content as i want to display the system wallpaper in the transparent areas.
finally setting up the PorterDuffXfermode correctly solved the issue. Just overwrite the dispatchDraw method of the parent viewgroup and erase the required areas using PorterDuff.
Sometimes it looks like the direction does matter how the path for drawPath is created (CW or CCW). So maybe try both.
Unfortunately this approach does not work if the hosted activity uses a SurfaceView on its own.
protected void dispatchDraw(Canvas canvas) {
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(getContext().getColor(android.R.color.white));
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
int save = canvas.save();
super.dispatchDraw(canvas);
canvas.drawPath(path, p);
canvas.restoreToCount(save);
}
I'm showing 96x96 pixel art sprites in imageviews and can't get it to display without applying anti-aliasing (or at least some form of interpolation, if it isn't anti-aliasing), which ruins the sharp edge of the sprites.
How can this be done? I've tried the following methods I've picked up from around the internet, but none work.
METHOD ONE
creating an xml resource file with a bitmap, and setting the anti-alias flag to false. Didn't work at all
METHOD TWO
creating a bitmap object from the resource, and setting the anti-alias flag to false. Didn't work at all.
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.dryad_back_large);
BitmapDrawable drawable = new BitmapDrawable(getResources(), bitmap);
drawable.setAntiAlias(false);
playerMonsterImageView.setImageDrawable(drawable);
METHOD THREE
Using sprites which are large enough so that they will never need to be scaled down, only up (512x512 worked for me)
So this third method WORKS, but it seems really ham-fisted, and I was hoping there was a better way of going about this.
Maybe there's something other than anti-aliasing going on here that I've missed?
There are multiple things that may be scaling your image with anti-aliasing.
One is BitmapFactory. For example, if you have a drawable-mdpi resource and the current resource configuration is xhdpi, it will scale at decode time. You can provide options to avoid this, but the easiest way around it is to put these resources in drawable-nodpi.
The canvas also scales the image with bilinear sampling by default. To avoid that, use a Paint with .setFilterBitmap(false) when drawing to the Canvas. One way to do that is by using a custom Drawable which wraps the underlying .draw() call with a DrawFilter modifying the desired paint flags.
public class AliasingDrawableWrapper extends DrawableWrapper {
private static final DrawFilter DRAW_FILTER =
new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
public AliasingDrawableWrapper(Drawable wrapped) {
super(wrapped);
}
#Override
public void draw(Canvas canvas) {
DrawFilter oldDrawFilter = canvas.getDrawFilter();
canvas.setDrawFilter(DRAW_FILTER);
super.draw(canvas);
canvas.setDrawFilter(oldDrawFilter);
}
}
imageView.setDrawable(new AliasingDrawableWrapper(getDrawable(R.drawable.bitmap)));
In "METHOD TWO", set the filter of the Drawable to false with
drawable.setFilterBitmap(false);
instead of using the setAntialias method you mention.
I am developing an app that has private information and should not display a real screenshot in Android's recent app switcher. I've tried a variation of this solution, by setting the content view to an ImageView inside the onPause function, but it seems that the operating system takes a screenshot before the content view is changed to the custom image.
I am also aware of setting the window's layout parameter flags to secure, making the screenshot completely white, but I'd hope that there would be a way to customize the screenshot.
So, I'm wondering at what point that Android takes a screenshot of the app for the app switcher (specifically in KitKat and Lollipop).
EDIT
It is no longer possible to customize the screenshot which system uses to present the thumbnail in the recent apps.
Old answer
Take a look at method Activity.onCreateThumbnail - this is exactly what you're looking for as it let you draw your own thumbnail for Recent screen.
You get Canvas as one of the parameters in which you can draw (or not draw at all) directly. The main point is that you have to return true from this method, which indicates that system won't draw thumbnail itself.
The simpliest solution would be:
#Override
public boolean onCreateThumbnail (Bitmap outBitmap, Canvas canvas) {
// Do nothing or draw on Canvas
return true;
}
or if you want to draw your own Bitmap
#Override
public boolean onCreateThumbnail (Bitmap outBitmap, Canvas canvas) {
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.myBitmap);
canvas.drawBitmap(myBitmap, 0, 0, null);
return true;
}
I'm currently using the latest osmdroid library (3.0.10) to show my custom markers on a map with an ItemizedOverlay. I've extended the Drawable class to implement my own drawing. However my drawables are not drawn correctly. I draw a bitmap image, a circle and a text on top of each other. The bitmap is drawn, but the circle and the text is not visible. When I use the same drawable in an imageview, everything is OK.
Here is the code of my drawable's onDraw method:
#Override
public void draw(Canvas canvas) {
canvas.save();
canvas.translate(getBounds().left, getBounds().top);
//this draws fine
canvas.drawBitmap(bitmap, new Rect(0,0,bitmap.getWidth(),bitmap.getHeight()), new Rect(0,0,mWidth,mWidth), mPaint);
//this is not
canvas.drawCircle(mHeight/2, mHeight/2, mHeight/2, mPaint);
//neither
canvas.drawText("X", mHeight/2, mHeight/2, mPaint2);
canvas.restore();
}
I've tried drawing the circle and the text on a bitmap, and drawing that on the provided canvas. It's working but that kills the whole point.
Any help is appreciated.
After a day of going trough the osmdroid sources, i managed to resolve my problems, but haven't found why are they there in the first place. Osmdroid uses an ISafeCanvas interface (and SafeTranslatedCanvas implementation) to wrap a canvas to deal with some high zoom level translate glitches. While I haven't found any straightforward errors in the code, I bypassed the mechanics when drawing my overlays by overriding the ItemizedOverlay's draw method and making my own ISafeCanvas implementation, which only returns the encapsulated canvas in it's getSafeCanvas method, and now everything looks fine.
#Override
protected void draw(Canvas canvas, MapView mv, boolean shadow) {
drawSafe(new MyCanvas(canvas),mv,shadow);
}
This is far from a best solution, the SafeCanvas is there for a reason, so I suggest a thorough testing if using this method.
Note: I used only Android 4.1.1, and don't know if this issue is present on other devices.
Please take a look at Issue 427. Essentially you want to use:
canvas.getUnsafeCanvas(new UnsafeCanvasHandler() {
// Draw circle and text here
// (but not drawBitmap)
});
Keep an eye on the ticket for a more permanent solution.
I am trying to set a png image to fill the background of my canvas while still maintaining its aspect ratio. I start by converting it to a Bitmap:Then set the back ground using the setBitmap method from the Canvas class:
http://developer.android.com/reference/android/graphics/Canvas.html#Canvas(android.graphics.Bitmap)
public class PlayOn extends View{
Bitmap board;
public PlayOn(Context gamecontext) {
super(gamecontext);
board=BitmapFactory.decodeResource(getResources(),R.drawable.board_rev1);
}
#Override
protected void onDraw(Canvas mycanvas) {
super.onDraw(mycanvas);
mycanvas.setBitmap(board);
}
}
But once I go to the Activity that calls this extended View class I get an error saying my application stopped unexpectedly.
I've also tried playing around with some of the other functions in the Canvas and Bitmap class but nothing seems to work.
Please what is the best way to do this? I read on the android developer site that there is a way to set an image so that it is the canvas and other images can then be drawn inside it but I wasn't able to figure out how to do that.
Thanks!
You might want to add a Log.d to check that the board bitmap returned from
BitmapFactory.decodeResource(getResources(),R.drawable.board_rev1);
isn't null. But I am using the following to draw bitmaps to full screen views in onDraw in several applications, so if the bitmap is non-null that should work fine.
canvas.drawBitmap(mBitmap, 0, 0, null);
And there's a version of drawBitmap which scales, namely
void canvas.drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
Draw the specified bitmap, scaling/translating automatically to fill the
destination rectangle.
You might want to try that?