I have layout in that it contain a horizontal scroll scale.
My question is how make this type of zoom effect on the center of the layout?
Is it possible?
i have draw the scale in canvas and zoom the canvas??
Please help me.
Thank's in advance.
I think you want a Transformation: http://developer.android.com/reference/android/view/animation/Transformation.html
The code in your onDraw method will look something like this:
canvas.save();
transformation.transform(canvas);
drawable.draw(canvas);
canvas.restore();
Step 1: At first draw the scale(drawing) on a canvas.
Step 2: get the zooming region, and apply this region as the clipRegion on the canvas ..
Step 3: get the bitmap from the canvas, and draw it on the canvas applying scale on it,scaling pivot point will be the center point of the area you want to zoom,
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bitmap_object = Bitmap.createBitmap(width, height, conf);
Canvas canvas_object = new Canvas(bitmap_object);
/* now draw your drawing on canvas_object */
Bitmap temp = bitmap_object;
Matrix matrix_object = new Matrix();
/* now set transform and scale on matrix_object to zoom */
Paint paint_object = new Paint();
paint_object.setFilterBitmap(true);
Region reg= /* region of your zooming area */
canvas_object.clipRegion(reg);
canvas_object.drawBitmap(temp,matrix_object,paint_object);
Related
I'm trying to overlay a bitmap onto another, placing it at the location the user touches. Here's the code:
public static Bitmap mergeImage(Bitmap base, Bitmap overlay, float x, float y)
{
Bitmap mBitmap = Bitmap.createBitmap(base.getWidth(), base.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap);
canvas.drawBitmap(base, 0, 0, null);
canvas.drawBitmap(overlay, x, y, null);
return mBitmap;
}
The issue here is, even though the x & y coordinates are obtained correctly (I checked), the overlay bitmap does not place correctly.
When around the top left portion of the image, placement is correct. However, as I move right and down, the location seems to scale differently (i.e. if I touch the bottom right corner of the screen, the overlay places somewhere near the middle of the image, if I touch bottom left, it places near the middle left of the image and so on)
Both images have the same density (320).
Edit: New issue, i reduced the sizes of both images and now placement is roughly accurate. But saving the image to SD card skews the overlay image to a different (and quite random) location
I found the solution using Matrix for set location and scale x,y
public static Bitmap mergeImage(Bitmap base, Bitmap overlay, float x, float y)
{
Bitmap mBitmap = Bitmap.createBitmap(base.getWidth(), base.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(mBitmap);
Matrix matrix = new Matrix ();
matrix.postTranslate( x,y);
canvas.drawBitmap(base, 0, 0, null);
canvas.drawBitmap(overlay, matrix, null);
return mBitmap;
}
I spend something similar and I found the solution, you can see my post in the siguiete link
canvas.drawBitmap bad Location and size (not placing image correctly)
I want to rotate a bitmap image based on user click by 10 deg. Following numerous stackoverflow and google answers, I tried various combinations of Matrix rotation.
However the image doesn't really rotate as expected and gives a jittery view of rotation + oscillation about canvas center. To test I am increasing rotation angle by 10 deg (instead of clicks) each time object's draw method is called. The image is a symmetrical circle [64x64 enclosing rectangle] and I expect it to rotate at center of screen about it's own center like a wheel, but it rotates and moves diagonally towards right-down and moves back upto center of screen in an oscillatory fashion.
public void draw(Canvas canvas) {
Matrix matrix = new Matrix();
rotation += 10;
float px = this.viewWidth/2;
float py = this.viewHeight/2;
matrix.setRotate(rotation, bitmap.getWidth()/2, bitmap.getHeight()/2);
Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, getImgWidth(), getImgHeight(), matrix, true);
canvas.drawBitmap(newbmp, px - (getImgWidth()/2), py - (getImgHeight()/2), null);
}
Here is an example.
I broke it to 3 steps.
The first translate moves the bitmap so that it's center is at 0,0
Then a rotation,
and finally move the bitmap center to where you want it on the canvas.
You don't need the second bitmap.
Matrix matrix = new Matrix();
rotation += 10;
float px = this.viewWidth/2;
float py = this.viewHeight/2;
matrix.postTranslate(-bitmap.getWidth()/2, -bitmap.getHeight()/2);
matrix.postRotate(rotation);
matrix.postTranslate(px, py);
canvas.drawBitmap(bitmap, matrix, null);
As an optimization, create the Matrix once outside this method and replace the creation with a call to matrix.reset()
You need to translate the bitmap to the 0,0 point (or draw it at 0,0) and rotate it there, then translate it back, as such:
canvas.save();
canvas.translate(this.viewWidth, this.viewHeight);
canvas.rotate(rotation);
canvas.drawBitmap(newbmp, -(getImgWidth()/2), -(getImgHeight()/2), null);
canvas.restore();
Here I draw it with the center at 0,0 (I think), because when you rotate, it's about 0,0 and not the center of the screen as one would think. If you draw the center at 0,0 then it will rotate about the center of the bitmap.
If my code does not accomplish drawing the bitmap center at 0,0 then you can change my code to draw it at the center and it will work as you want.
Hope this helps!
// x : x coordinate of image position
// y : y coordinate of image position
// w : width of canvas
// h : height of canvas
canvas.save();
canvas.rotate(angle, x + (w/2), y + (h/2));
canvas.drawBitmap(image, x, y, null);
canvas.restore();
The steps are
Save the existing canvas
Rotate the canvas about the center of the bitmap, that you would draw on canvas with an angle of rotation
Draw the image
Restore the image
I have one image image 1 and one is coming from server that is image 2 i am trying to draw second one just at the center of the first. as result i want single image like in pic .
This should do what you're looking for:
The backgroundBitmap variable would be your image1 and the bitmapToDrawInTheCenter would be your image2.
public void centerImageInOtherImage()
{
Bitmap backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
Bitmap bitmapToDrawInTheCenter = BitmapFactory.decodeResource(getResources(), R.drawable.ic_action_search);
Bitmap resultingBitmap = Bitmap.createBitmap(backgroundBitmap.getWidth(), backgroundBitmap.getHeight(), backgroundBitmap.getConfig());
Canvas canvas = new Canvas(resultingBitmap);
canvas.drawBitmap(backgroundBitmap, new Matrix(), null);
canvas.drawBitmap(bitmapToDrawInTheCenter, (backgroundBitmap.getWidth() - bitmapToDrawInTheCenter.getWidth()) / 2, (backgroundBitmap.getHeight() - bitmapToDrawInTheCenter.getHeight()) / 2, new Paint());
ImageView image = (ImageView)findViewById(R.id.myImage);
image.setImageBitmap(resultingBitmap);
}
Courtesy : Draw text/Image on another Image in Android
Drawing images over each other is fairly simple with Canvas. Canvas basically acts as the drawing board to draw text/Image. You just need to construct a canvas with the first Image and then draw the second Image at the center as shown below
/* This ImageOne will be used as the canvas to draw an another image over it. Hence we make it mutable using the copy API
as shown below
*/
Bitmap imageOne = BitmapFactory.decodeResource(getResources(), R.drawable.imageOne).copy(Bitmap.Config.ARGB_8888,true);
// Decoding the image two resource into a Bitmap
Bitmap imageTwo= BitmapFactory.decodeResource(getResources(), R.drawable.imageTwo);
// Here we construct the canvas with the specified bitmap to draw onto
Canvas canvas=new Canvas(imageOne);
/*Here we draw the image two on the canvas using the drawBitmap API.
drawBitmap takes in four parameters
1 . The Bitmap to draw
2. X co-ordinate to draw from
3. Y co ordinate to draw from
4. Paint object to define style
*/
canvas.drawBitmap(imageTwo,(imageOne.getWidth())/2,(imageOne.getHeight())/2,new Paint());
imageView.setImageBitmap(imageOne);
I want to set a background of a View with a tiled bitmap, but the tiling needs to be anchored to the bottom-left, instead of the top-left corner (the default). For example, if the tiles are the smiley faces below, I want it to be tiled like:
Using xml drawables I could achieve either tiling (using tileMode="repeat") or bottom positioning (using gravity="bottom"), but combining both is not possible, even the documentation says so:
android:tileMode
Keyword. Defines the tile mode. When the tile mode is
enabled, the bitmap is repeated. Gravity is ignored when the tile mode
is enabled.
Although it's not internally supported, is there any way to achieve this, perhaps using custom views?
Another way would be to extend BitmapDrawable and override the paint() method:
In this method we avoid creating a new bitmap having the size of the view.
class MyBitmapDrawable extends BitmapDrawable {
private Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.DITHER_FLAG);
private boolean mRebuildShader = true;
private Matrix mMatrix = new Matrix();
#Override
public void draw(Canvas canvas) {
Bitmap bitmap = getBitmap();
if (bitmap == null) {
return;
}
if (mRebuildShader) {
mPaint.setShader(new BitmapShader(bitmap, TileMode.REPEAT, TileMode.REPEAT));
mRebuildShader = false;
}
// Translate down by the remainder
mMatrix.setTranslate(0, getBounds().bottom % getIntrinsicHeight());
canvas.save();
canvas.setMatrix(mMatrix);
canvas.drawRect(getBounds(), mPaint);
canvas.restore();
}
}
It can be set to the view like this:
view.setBackgroundDrawable(new MyBitmapDrawable(getResources().getDrawable(R.drawable.smiley).getBitmap()));
Just a thought, and it's pretty roundabout, but could you flip your image vertically, and then apply a transform to your background to flip that vertically as well?
Using a custom view might involve handling all the drawing yourself, not just the background image.
Instead, I propose to set the view's background programmatically as shown:
// This drawable refers to an image directly and NOT an XML
BitmapDrawable smiley = (BitmapDrawable) getResources().getDrawable(R.drawable.smiley);
// Create a new bitmap with the size of the view
Bitmap bgBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bgBitmap);
// Translate down by the remainder
Matrix matrix = new Matrix();
matrix.setTranslate(0, view.getHeight() % smiley.getIntrinsicHeight());
canvas.setMatrix(matrix);
// Tile the smileys
Paint paint = new Paint();
paint.setShader(new BitmapShader(smiley.getBitmap(), TileMode.REPEAT, TileMode.REPEAT));
canvas.drawPaint(paint);
view.setBackgroundDrawable(new BitmapDrawable(bgBitmap));
Points to consider:
I'm not sure if view.getWidth() & view.getHeight() are the correct
methods to get the dimensions.
What if smiley size is bigger than the view?
I use that Google Maps component MapView in an Android application. I can use the GPS location to show my location with a dot. But I would like to show an arrow instead, that points out the driving direction (bearing). I think that I can use the bearing value to get the angle of the arrow.
How can I do that?
Assuming you've got the Location then obtain the bearing by doing:
float myBearing = location.getBearing();
To implement the overlay you'll be using ItemizedOverlay and OverlayItem. You'll need to subclass OverlayItem to add the functionality to rotate the Drawable. Something like:
public BitmapDrawable rotateDrawable(float angle)
{
Bitmap arrowBitmap = BitmapFactory.decodeResource(context.getResources(),
R.drawable.map_pin);
// Create blank bitmap of equal size
Bitmap canvasBitmap = arrowBitmap.copy(Bitmap.Config.ARGB_8888, true);
canvasBitmap.eraseColor(0x00000000);
// Create canvas
Canvas canvas = new Canvas(canvasBitmap);
// Create rotation matrix
Matrix rotateMatrix = new Matrix();
rotateMatrix.setRotate(angle, canvas.getWidth()/2, canvas.getHeight()/2);
// Draw bitmap onto canvas using matrix
canvas.drawBitmap(arrowBitmap, rotateMatrix, null);
return new BitmapDrawable(canvasBitmap);
}
Then all that remains to be done is to apply this new Drawable to the OverlayItem. This is done using the setMarker() method.