I have a canvas-based drawing app that when zoomed in, I draw a miniature of the overall drawing in one corner as a scaled Bitmap. I also have a small RectF that I draw over top of the miniature, which shows you where you are in the drawing. See first attached image.
What I would like to do is to draw the scaled bitmap, then draw a RectF of the same size over top of it, with an alpha value that allows you to see the miniature, and then finally, punch a hole in the RectF that shows you where you are and allows you a clearer view of the miniature. See second attached image.
I've considered using a bitmap for the RectF with the hole already 'built-in', but as the hole will both be moving depending on location, and will change in size depending on scale factor, I need to do it dynamically.
I've looked over the RectF docs but don't see anything that would allow me to clip the RectF with a smaller RectF that would make the 'hole'. Any ideas?
You could use a Path with filling option.
moveTo 0,0 and frame the whole minipic, then moveTo the first corner inside and frame/create the hole. Not sure if it works but you can also add shapes to the path.
Related
So on my canvas I have few rectangular areas where I draw different bitmaps.
Sometimes bitmaps get outside of their respective areas. I want these bitmaps to be cut off, so only the portion of bitmap inside of it's area is drawn.
I sure can calculate it manually (srcRect and dstRect)...
But isn't there a simpler solution?
I found clipBounds, but it doesn't seem to restrict drawing area in any way.
What you want is Canvas.clipRect(). You will need to know the bounds of the clipping rectangle, of course, but you don't need to worry about calculating a custom srcRect.
To use, save() the Canvas, do a single drawBitmap(), then restore() it to get your original clipping state back:
canvas.save();
canvas.clipRect(...);
canvas.drawBitmap(...);
canvas.restore();
Suppose, we've got a display sized 100x100, an image 100x50, and I want to enlarge that image so that it has the same height as the screen does. So the image will be 200x100. After that I want to make the animation of image movement to the left and to the right. I've found 2 ways of the realization of my task:
To create a new image using Bitmap.createScaledBitmap(). But the
image created this way will occupy twice more RAM.
To use matrix.setScale() in every onDraw(). But this works very
slow. Is there any other better solution?
The second method is slow because you calculate your "matrix" on every frame! Since your matrix is always the same thing and it does not change, you can pre-calculate your matrix and save it as a "field" in you class, then just use this function to draw it on screen:
canvas.drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)
It should be fast enough. The other option is to use:
canvas.drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
Again, try to pre-calculate stuff as much as possible. In this case, pre-calc src and dst rectangles.
I have a bitmap out of which I'm cutting out a multipi point polygon. I'm curious what the correct process is for taking the pixels within the arbitrary shape and copying them onto a new bitmap where the rest of the pixels are transparent. The objective is to allow the user to trace the shape and then remove everything outside the polygon.
I have the polygon part worked out (as a an array of points), but now am stumped as to how to transfer just the selected pixels to a new Bitmap.
TIA
Not sure how your code works, but here's an idea on how to do it:
Calculate the bounding rectangle of the selected area (find min x, min y, max x and max y from your points).
Crop your image to the bounding rectangle using any of the Bitmap or Canvas-methods.
Create a Path from your points, all moved into your new bitmap (x-=minX, y-=minY);
Set your Paths FillType to one that is inverse (fill the outside).
On your new cropped canvas, draw the Path using a paint with the Xfermode as PorterDuff.CLEAR, which removes all color.
Android Question.
I have made a custom ImageView class and inside it I have an onDraw method which will draw a circle on particular pixels (using canvas). When I use this custom imageview and open up my image I would like to set the focus on the circle that I have drawn (e.g like google maps do with your current location. The focus is set to your current point)
What the map server does on google is deliver a customized set of tiles so that the center is displayed properly, the newer version is of course vector based so they simply draw the view so it's centered where they want it.
Without knowing the details of your application you probably need
Create your own container class, probably FrameLayout
public class myMapFrameLayout extends FrameLayout {
The override either onDraw or onDispatchDraw so that you can layout your tile appropriately
Figure out where to draw your bitmap so that the x,y you need will be in the center of the screen, then draw the other tiles that you need to fill in the blank space at the coordinates required dependent on which way the tile was moved to get centered
Think of a virtual screen that is larger than the actual screen with tiles all around it that are the same size
1 2 3
4 X 5
6 7 8
Assuming that X is the size of the display and represents the current tile you need to figure out which way to move the tile, and which other tiles 1,2,3,4,5,6,7 or 8 you need to fill in the empty space caused by move
If you had to draw the tile +x from 0,0 you need some of tile 4, drawing +y from 0,0 means some of 2 and both mean 1,2,4 are all needed and so on, so figure out the combinations and load the tiles you need, and figure out the drawing positions of each. That would give you your new virtual tile with the center displayed.
That's about as efficient as you can get I think with a bitmap drawing method on the client side.
UPDATE
Since your comment indicates you have only one very large image this is going to be a bit of a problem if the x,y you need as anything closer to the edges than the size of the display
None the less you can still draw the image where you need it, just measure the screen and draw the bitmap with the target x,y in the center
So if the screen was 500x500 and your image was 5000x5000 and the center was at position x=1000 y=1000 then
drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint)
where source rectangle would be 1000-250,1000-250,500,500 and dst rectangle would be 0,0,500,500
The 250 is the center x and center y of the display, 1000 are the target x/y coordinates, and 500 is the size of display.
Again, with targets that are at the edges you are going to have a blank polygon in your screen since you dont have an infinite map tile
Alternatively you could oversize your framelayout using layoutparams and just translate the canvas in the x and y to get the canvas centered to the x,y you need using similar calcs which may be more performant, not really sure
Keep in mind you are going to be using a lot of memory if your image is really big
I'm writing my first app of any consequence, so I may be going about this the entire wrong way, but...
I have a resource image that is 1600x880. I'd like to fill the entire screen with a subset of that image to my canvas, such that an arbitrary x,y coordinate marks the top-left corner drawn at the top-left corner of the screen. For instance, if I was viewing this image on an N1 and I entered x=100 and y=50, I'd expect to see from 100,50 to 580,850 since it's display area is 480x800.
I think I need to use Canvas.drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint). But, no matter what I plug in to either Rect (even if it's a perfectly sane set of values that shouldn't butt up against any edges of the image), I end up with an unexpected area or a grossly stretched/smooshed output.
I've tried using various combinations of calculations involving display.getWidth() and getHeight(), canvas.getWidth() and getHeight(), and bitmap.getWidth() and getHeight() but nothing seems to be working.
I don't know what I'm doing wrong.