Android Crop parent bitmap with the child co-ordinates - android

I have two ImageView/Bitmap, one for visible background and it not movable one, Another one is movable bitmap on the background view. The movable bitmap have pinch zoom and rotate with matrix. Finally find movable co-ordinates/rect position and crop background bitmap using those rect position. My question is how to calculate/get rect position?.
For my sample, what i need for your view. Pleas post your idea here, it help to every one.

I spend more time to search and after few weeks for get this result.
private Bitmap getCroppedBmp(Bitmap childBmp, Bitmap ParentBmp) {
// viewBmp is movable bitmap, orgBitmap is Parent Bitmap
Bitmap viewBmp = childBmp;
Bitmap orgBitmap = ParentBmp;
float[] v = new float[9];
// get Matrix from View
cropImage.savedMatrix.getValues(v);
float left = v[Matrix.MTRANS_X];
float top = v[Matrix.MTRANS_Y];
// calculate the degree of rotation
float rAngle = Math.round(Math.atan2(v[Matrix.MSKEW_X],
v[Matrix.MSCALE_X]) * (180 / Math.PI));
// Rotate viewBmp
Matrix m = new Matrix();
m.postRotate(rAngle, viewBmp.getWidth() / 2, viewBmp.getHeight() / 2);
Bitmap bmap = Bitmap.createBitmap(viewBmp, 0, 0, viewBmp.getWidth(),
viewBmp.getHeight(), m, true);
// calculate real scale
float rScale = (float) Math
.sqrt((v[Matrix.MSCALE_X] * v[Matrix.MSCALE_X])
+ (v[Matrix.MSKEW_Y] * v[Matrix.MSKEW_Y]));
// Scale viewBmp
Matrix m1 = new Matrix();
m1.postScale(rScale, rScale, width / 2, height / 2);
Bitmap scaledBitmap = Bitmap.createBitmap(bmap, 0, 0, width, height,
m1, true);
// Finally Get cropped Bitmap
Bitmap resultingImage = Bitmap.createBitmap(orgBitmap, (int) left,
(int) top, scaledBitmap.getWidth(), scaledBitmap.getHeight());
return resultingImage;
}

Related

DrawBitmap with Matrix not Accurate

I'm trying to use Canvas.drawBitmap(...) to draw Bitmaps onto a Canvas but it's not appearing in the correct position or size.
Below is an example on how I'm attempting to achieve this:
Canvas canvas = new Canvas();
Matrix matrix = new Matrix();
/// scale = 0.5
/// image.getX() = 250
/// image.getY() = 250
matrix.setTranslate(
imageView.getX() * scale,
imageView.getY() * scale
);
matrix.setScale(
scale,
scale
);
matrix.postRotate(imageView.getRotation(), imageView.getX() * scale, imageView.getY() * scale);
canvas.drawBitmap(bitmap, matrix, null);
The result that I'm getting is that the image is at the original size at 0x0 position.
The expected result is for the image to be half-size and in the center of the canvas.
NOTE: I'm using matrix.postRotate(...) to draw the bitmap rotated to the same angle as the ImageView.
Can you give this a shot, I have tried to explain the logic in the comments:
// as you wanted Half size so reduced width and height to half
Bitmap dstBitmap = Bitmap.createScaledBitmap(srcbitmap,(srcbitmap.getWidth()/2 ),(srcbitmap.getHeight()/2),true);
// Here I calculate screen size
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
//Create screen size bitmap to position image at center easily
Bitmap bitmap = Bitmap.createBitmap(
width,
height,
Bitmap.Config.ARGB_8888
);
// Initialize a new Canvas with above bitmap
Canvas canvas = new Canvas(bitmap);
Matrix matrix = new Matrix();
// Rotating about center of image
matrix.setRotate(
45, // your angle
dstBitmap.getWidth() / 2,
dstBitmap.getHeight() / 2
);
matrix.postTranslate(
(width - dstBitmap.getWidth()) / 2,
(height - dstBitmap.getHeight() )/ 2
);
canvas.drawBitmap(dstBitmap, matrix, null);
Now you should be good to proceed , this should give you correct output

Watermark coming on whole image Android

I want to place the watermark on the bottom right of the picture. But, in some mobiles it is coming perfectly and in some mobile phones, the watermark is coming on the whole image.
Here is my code:
rotatedBitmap = Bitmap.createBitmap(loadedImage, 0, 0,
loadedImage.getWidth(), loadedImage.getHeight(),
rotateMatrix, false);
int w = rotatedBitmap.getWidth();
int h = rotatedBitmap.getHeight();
Bitmap result = Bitmap.createBitmap(w, h, rotatedBitmap.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(rotatedBitmap, 0, 0, null);
Bitmap waterMark = BitmapFactory.decodeResource(getResources(), R.drawable.watermark2);
int ww = waterMark.getWidth();
int hh = waterMark.getHeight();
canvas.drawBitmap(waterMark,(w-ww),(h-hh), null);
EDIT: Here are the screenshots of the result. In second picture, the watermark is coming perfectly and in first picture, it is coming on the whole picture.
Make use of aspect ratio. Calculate aspect ratio of device and accordingly calculate appropriate size for your water mark.
How to calculate aspect ratio?
Check for width and height of screen whichever is bigger divide it by smaller one
example:
if(screen_width > screen_height){
aspectRatio = screen_width/screen_height
}else{
aspectRatio = screen_height/screen_width
}
now that you have calculated aspect ratio multiply it with size of you water mark and scale it accordingly.
like:
float ww = watermark.getWidth()*aspectRatio;
float wh = watermark.getHeight()*aspectRatio;
and use these values.
Hope this helps...
Just Give ratio and you go to go,try changing ratio values that best fit for your src bitmap .
Embeds an image watermark over a source image to produce a
watermarked one.
#param source The source image where watermark should be placed
#param ratio A float value < 1 to give the ratio of watermark's
height to image's height,
try changing this from 0.20 to 0.60 to obtain right results
public static Bitmap addWatermark(Context context, Bitmap source, float ratio)
{
Canvas canvas;
Paint paint;
Bitmap bmp;
Matrix matrix;
RectF r;
int width, height;
float scale;
Bitmap waterMark = BitmapFactory.decodeResource(context.getResources(), R.drawable.watermark3x);
width = source.getWidth();
height = source.getHeight();
// Create the new bitmap
bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
// Copy the original bitmap into the new one
canvas = new Canvas(bmp);
canvas.drawBitmap(source, 0, 0, paint);
// Scale the watermark to be approximately to the ratio given of the source image height
scale = (float) (((float) height * ratio) / (float) waterMark.getHeight());
// Create the matrix
matrix = new Matrix();
matrix.postScale(scale, scale);
// Determine the post-scaled size of the watermark
r = new RectF(0, 0, waterMark.getWidth(), waterMark.getHeight());
matrix.mapRect(r);
// Move the watermark to the bottom right corner
matrix.postTranslate(width - r.width(), height - r.height());
// Move the watermark to the bottom left corner
// matrix.postTranslate(0 , height - r.height());
// Move the watermark to the top-left corner
// matrix.postTranslate(0 ,0);
// Move the watermark to the top right corner
// matrix.postTranslate(width - r.width(), 0l̥);
// Draw the watermark
canvas.drawBitmap(waterMark, matrix, paint);
return bmp;
}

how to rotate image using latitude and longitude

hello i want to rotate image view by latitude and longitude suppose i have
lat/LNG: (33.6343541968021,73.06278146803379)
now i want my image-view(needle) point this location how i can do this?
i am doing this
public void onSensorChanged(SensorEvent event) {
float degree = Math.round(event.values[0]);
RotateAnimation ra1 = new RotateAnimation(
currentDegree,
-degree,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF,
0.5f);
// how long the animation will take place
ra1.setDuration(0);
// set the animation after the end of the reservation status
ra1.setFillAfter(true);
compass_img.startAnimation(ra1);
currentDegree= -degree;}
i am using orientation sensor
Try this way
// Get the image we want to work with from a URL
Bitmap myBitmap = BitmapFactory.decodeStream(downloadImageFromWeb());
// or just load a resource from the res/drawable directory:
Bitmap myBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.android1);
// find the width and height of the screen:
Display d = getWindowManager().getDefaultDisplay();
int x = d.getWidth();
int y = d.getHeight();
// get a reference to the ImageView component that will display the image:
ImageView img1 = (ImageView)findViewById(R.id.img1);
// scale it to fit the screen, x and y swapped because my image is wider than it is tall
Bitmap scaledBitmap = Bitmap.createScaledBitmap(myBitmap, y, x, true);
// create a matrix object
Matrix matrix = new Matrix();
matrix.postRotate(-90); // anti-clockwise by 90 degrees
// create a new bitmap from the original using the matrix to transform the result
Bitmap rotatedBitmap = Bitmap.createBitmap(scaledBitmap , 0, 0, scaledBitmap .getWidth(), scaledBitmap .getHeight(), matrix, true);
// display the rotated bitmap
img1.setImageBitmap(rotatedBitmap);
Check Create our Android Compass and Rotating a Bitmap in Android

Rotate around alternate axis

I am struggling with bitmap rotations. I wish to rotate a graphic around an alternate axis but I can only ever get it to rotate around the center point no matter what I do, putting in postTranlate. preTranslate, set Translate in any order doesnt work I have also tried the postRotate(45,0,0) but it always rotates around the center.
Code below taken of internet what would I do to alter its rotation point, the code below uses the launcher icon which is square I am using a long thin graphic like an arrow.
// Rotate image to 45 degrees.
public void RotateImage(){
ImageView image;
Bitmap bMap;
Matrix matrix;
//Get ImageView from layout xml file
image = (ImageView) findViewById(R.id.imageView1);
//Decode Image using Bitmap factory.
bMap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
//Create object of new Matrix.
matrix = new Matrix();
//set image rotation value to 45 degrees in matrix.
matrix.postRotate(45);
//Create bitmap with new values.
Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0,
bMap.getWidth(), bMap.getHeight(), matrix, true);
//put rotated image in ImageView.
image.setImageBitmap(bMapRotate);
}
I have tried the code below but its still rotates around the center or at least appears too
public void RotateImage{
ImageView image;
Bitmap bMap;
Matrix matrix;
//Get ImageView from layout xml file
image = (ImageView) findViewById(R.id.imageView);
//Decode Image using Bitmap factory.
bMap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
//Create object of new Matrix.
matrix = new Matrix();
//set image rotation value to 45 degrees in matrix.
matrix.setTranslate(-100,-200);
matrix.postRotate(angle);
matrix.postTranslate(100,200);
//Create bitmap with new values.
Bitmap bMapRotate = Bitmap.createBitmap(bMap, 0, 0,
bMap.getWidth(), bMap.getHeight(), matrix, true);
//put rotated image in ImageView.
image.setImageBitmap(bMapRotate);
Thanks
If you want your Bitmap to rotate 45 degree around x axis with pivot (a,b), you can call matrix.rotate(45, a, b)
Perhaps you want to use the Camera class to rotate around X, Y or Z axis:
matrix = new Matrix();
Camera camera = new Camera();
camera.save();
camera.rotateX(45f);
camera.getMatrix(matrix);
camera.restore();
The way I understand your question is that you want to rotate the image around some point, say (x, y). Conceptually you need to perform the following transformations on the image:
Translate by (-x, -y)
Rotate by 45 degrees
Translate by (x, y)
You can use this method to rotate an object from center create this method in sprite class
public void paintFromCenter(float angle, Canvas c) {
Bitmap b = sprite;
Bitmap h = b;
// Canvas canvas = new Canvas(a);
Matrix matrix = new Matrix();
matrix.postRotate(angle, h.getWidth() / 2, h.getHeight());
matrix.postTranslate(getX(), getY());
// canvas.drawBitmap(bitmap, matrix, new Paint());
Bitmap bmp2 = Bitmap.createBitmap(h, 0, 0, frameWidth, frameHeight,
matrix, true);
c.drawBitmap(h, matrix, null);
// g.getCanvas().drawBitmap(bmp2, getX(), getY(), null);
}
Now in onTouchEvent()
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
evX = (int) event.getX();
evY = (int) event.getY();
int initX = objectSprite.getX();
int inity = objectSprite.getY();
if ((evX > objectSprite.getX()
&& evX < objectSprite.getX() + objectSprite.getWidth()
&& evY > objectSprite.getY() && evY < objectSprite.getY()
+ objectSprite.getHeight())) {
if (angle < 90) {
angle += 5;
} else if (angle < -180)
angle -= 5;
}
}
return true;
}
in draw() method paint the image/object
private void draw(Canvas canvas) {
objectSprite.paintFromCenter(angle, canvas);
}
try it

Android: Rotation of image around the center

I'm trying to rotate an image around the center. This works generally using RotateAnimation, but I want to have it a bit faster. I'm now using the SurfaceView pattern with a separate drawing thread.
This is code, which draws the bitmap correctly (depending on the outer "heading")
heading = angle in degrees,
bitmap = the bitmap,
w = width of the bitmap,
h = height of the bitmap.
Matrix m = new Matrix();
m.preRotate(heading, w/2, h/2);
m.setTranslate(50,50);
canvas.drawBitmap(bitmap, m, null);
Drawback: The image is a circle and the code above produces visible aliasing effects...
The code below is also rotating the image, but while rotating (say from 0 to 45 degrees clockwise) the center of the new image moves bottom/right. I suppose, the eccentric effect is due to the enlarged width/height of the new image ?? However, this code doesn't produce aliasing, if filter=true is set. Is there a way to use code #1 but have sort of anti-aliasing or use code #2 but getting rid of the center movement?
Matrix m = new Matrix();
m.preRotate(heading, w/2, h/2);
m.setTranslate(50,50);
Bitmap rbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, m, true);
canvas.drawBitmap(rbmp, 50, 50, null);
UPDATE: As result of the discussion in this thread the correct version of code #2 (anti-aliasing and correct rotation) would look like this (offset of 50,50 omitted):
Matrix m = new Matrix();
m.setRotate(heading, w/2, h/2);
Bitmap rbpm = Bitmap.createBitmap(bitmap, 0, 0, w, h, m, true);
canvas.drawBitmap(rbpm, (w - rbpm.getWidth())/2, (h - rbpm.getHeight())/2, null);
Thanks.
Find the center of the original image and for the new image and center using that:
Matrix minMatrix = new Matrix();
//height and width are set earlier.
Bitmap minBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas minCanvas = new Canvas(minBitmap);
int minwidth = bitmapMin.getWidth();
int minheight = bitmapMin.getHeight();
int centrex = minwidth/2;
int centrey = minheight/2;
minMatrix.setRotate(mindegrees, centrex, centrey);
Bitmap newmin = Bitmap.createBitmap(minBitmap, 0, 0, (int) minwidth, (int) minheight, minMatrix, true);
minCanvas.drawBitmap(newmin, (centrex - newmin.getWidth()/2), (centrey - newmin.getHeight()/2), null);
minCanvas.setBitmap(minBitmap);

Categories

Resources