I am working on a project for android devices. I want to split a bitmap image by a line into 2 bitmaps. How do I do this?
If resulting bitmaps are rectangular, i. e. line is either horizontal or vetical - you need to use this method of a canvas:
drawBitmap
You just create new bitmaps and use this methods for partial drawing of original bitmaps on its Canvas.
Otherwise - more tricky, I suppose you will need using masks and color blending using PorterDuff alghorithm (all is available through Canvas API) or just clip with a Path.
Related
Hi,
I'm trying to understand how to make custom view (with green background) on Android like represented on attached image. Please suggest, should I use Path for this or something else?
A good starting point would be http://tips.androidhive.info/2013/09/android-layout-rounded-corner-border/ . Then you can play with the attribute values to get the desired background. Hope this helps.
You have two good options for accomplishing this.
Bitmap
Create the desired image in Photoshop, Gimp or something similar. Export it as a png file then import it as a bitmap resource into your Android application.
This is by far the simpler and faster of the two methods, but here are two significant problems. First, you should supply bitmaps for each screen density bucket. Second, each bitmap resource you add increases the install size of your app. This can get out of hand quickly.
Path
As you mentioned in your question, you can draw the desired shape directly onto a canvas using a Path. More specifically, you'll use the cubicTo() method to create bezier curves.
I recommend using your image editor's "path" tool to learn how the control points affect the curve. Once you've drawn the shape in the image editor, write down the coordinates for every point on your path as well as the corresponding control points. Then do a little math to convert the points to ratios of the image's overall width and height.
You can implement the shape in your app as a View or as a Drawable. In either case, you'll be drawing to a Canvas. The important step will be to set up the path by multiplying the ratios with the size of your drawing area. After you draw the fancy edge, be sure to draw the straight edges via lineTo() and to close the shape with close().
I have two images one over other. Uppper image is having some transparent portion, I want to cut that portion and place it in sd card.
Also the below image can be zoomed in/out/scaled.
Can any one help me in this ?
I appreciate if anyone even can provide me some idea.
Create a Bitmap object to draw to that is the same size as the Upper image.
Create a Canvas object and pass this bitmap to its constructor so that you are drawing into the bitmap.
Draw the Lower image on the canvas with a transformation Matrix that represents your zoom/pan etc.
Then iterate over the pixels in the upper bitmap and the one you just drew into and set the alpha value of the pixels in the new bitmap to that in the upper image. Maybe there is another way of applying an alpha mask but I did not see one after a quick skim of the Canvas class interface - maybe looking a bit closer would reveal something.
Alternatively for better performance, use OpenGL and write a shader to do it using your two images. You can render to texture and pull the data back from the render texture. More complicated to do than the other method.
I am trying to create a Analog Meter in OpenGL ES 1.x on Android. I have created a simple circle using Midpoint Theorem in green color. Now I want to place some numbers around the circle for Meter readings. Since OpenGL has no native text rendering API, I am trying to load an PNG image like this with the reading on it and the rest of image is transparent.
Now what parameters I must pass to glBlendFunc() function to achive this.
I have tried many different combinations but nothing works.
This is a common problem on Android. You can't use the Android Bitmap class to load textures that have transparent areas in them. This is because Bitmap follows the Porter-Duff specification for alpha blending, and Bitmap optimizes images with per-pixel alpha by storing them in the premultiplied format (A, R*A, G*A, B*A). This is great for Porter-Duff but not for OpenGL, which requires a non-premultiplied (ARGB) format. This means that the Bitmap class can only be used with textures that are completely opaque (or have no per-pixel alpha). This article details:
http://software.intel.com/en-us/articles/porting-opengl-games-to-android-on-intel-atom-processors-part-1
Just try passing the Alpha Blending values which are:
glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
I hope it helps.
I don't think(even at 2.2)Alpha PNGs are problem for the Android Bitmap loading algorithm.
In Android, is there a clean way to display only a given part of a bitmap in an ImageView (for example a single sprite of a sprite sheet), without having to :
Manually split the bitmap png into small pngs (=> more drawables embedded in the app, tedious manual operation possibly leading to bugs, or loose the spritesheet).
Have small pngs used in the ImageViews, with the sprite sheet being generated (=> complicated)
Create "dirty" subclasses for ImageView, Drawable, etc (=> the more we use Android API "ASIS" the better)
Programmatically create sub-bitmaps of the big bitmap (=> We have to do all the work programmatically)
For instance I have tried creating an ImageView of width/height of 40dp, and setting its drawable as a ClipDrawable displaying only the part of the bitmap I wanted, but it did not go well :
the clipped part did not fill the parent when using Gravity.CENTER when creating the ClipDrawable.
The whole "big" PNG was displayed when using Gravity.FILL.
Furthermore this solution is feasable with a simple sprite sheet (for example 2*2 sprites), but I do not think it is possible when using something like a 4*4 sprite sheet. I think ClipDrawable is not meant for such a use.
Isn't there something "clean and easy" like in OpenGL where you can set a texture Id, and set the texture coordinates to display only part of the texture? Considering my researchs I think the best solution is to manually split the big bitmap with Bitmap.createBitmap, when I'd rather ask before starting something like that.
PS : I consider using SpriteSheets because of OpenGl, although my "menus" are developed using Android APIs, hence using ImageView.
Are you familiar with Canvas at all? I think that is another way that would work for you.
You create one bitmap in memory, then use drawBitmap to draw just the current chunk you want.
Here is a snippet from the manual:
public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint paint)
This function ignores the density associated with the bitmap. This is because the source and destination rectangle coordinate spaces are in their respective densities, so must already have the appropriate scaling factor applied.
Parameters
bitmap The bitmap to be drawn
src May be null. The subset of the bitmap to be drawn
dst The rectangle that the bitmap will be scaled/translated to fit into
paint May be null. The paint used to draw the bitmap
How can you blit a non-rectangular (e.g. oval) part of a bitmap into a canvas on Android?
Consider how you'd blit a rectangular part of a bitmap:
canvas.DrawBitmap(src,src_rect,dest_rect,paint). Sadly there is no corresponding methods for non-rectangular regions.
Four approaches present themselves (maybe you know a fifth?):
copy the rectangular bounds you want to blit into an intermediate bitmap, and go setting the pixels you don't want to blit to be transparent, then draw that bitmap
make a mask bitmap - there are ways to blit with a separate mask?
use a BitmapShader with drawArc()/drawCircle(); however, I can't work out how to get the matrix to be properly aligned; how would you initialize the matrix for this operation?
use a very very complicated clipping region
Of these, option 3 is the one that I would most like to work; however, I cannot work out how to do so; can you?
You can use option number #3, it's probably the easiest. Another way is to draw the shape you want to clip with in an intermediate Bitmap (ARGB8888), then draw your original Bitmap using a DstIn or DstOut xfermode.