I'm preparing somecompass activity.
I have my rose of winds .png and I want to scale it on activity start and rotate after orientation changed.
The problem is that when i scale my image (onCreate only), after first (and only first) use of rotate method my view is resized one more time, and I have no idea why.
Let me post you my rotate and scale methods. rose is my ImageView instance (ImageView rose)
Please take a look and post any advices. Should I try different way to scale my ImageView ?
Thx for any help !
Rotate (looks like working fine)
public void rotateRose(float angle){
angle = 360 - angle;
Matrix matrix=new Matrix();
rose.setScaleType(ScaleType.MATRIX);
pivX = rose.getDrawable().getBounds().width()/2;
pivY = rose.getDrawable().getBounds().height()/2;
matrix.preRotate((float) angle, pivX, pivY);
rose.setImageMatrix(matrix);
}
Scale (found source link)
private void scaleImage(ImageView view, int boundBoxInDp)
{
// Get the ImageView and its bitmap
Drawable drawing = view.getDrawable();
Bitmap bitmap = ((BitmapDrawable)drawing).getBitmap();
// Get current dimensions
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// Determine how much to scale: the dimension requiring less scaling is
// closer to the its side. This way the image always stays inside your
// bounding box AND either x/y axis touches it.
float xScale = ((float) boundBoxInDp) / width;
float yScale = ((float) boundBoxInDp) / height;
float scale = (xScale <= yScale) ? xScale : yScale;
// Create a matrix for the scaling and add the scaling data
Matrix matrix = new Matrix();
matrix.postScale(scale, scale);
// Create a new bitmap and convert it to a format understood by the ImageView
Bitmap scaledBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
BitmapDrawable result = new BitmapDrawable(scaledBitmap);
width = scaledBitmap.getWidth();
height = scaledBitmap.getHeight();
// Apply the scaled bitmap
view.setImageDrawable(result);
// Now change ImageView's dimensions to match the scaled image
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) view.getLayoutParams();
params.width = width;
params.height = height;
view.setLayoutParams(params);
//pivX = width/2;
// pivY = height/2;
}
Ok i've got it !
replace
view.setImageDrawable(result);
in Scale method with
view.setImageBitmap(scaledBitmap);
If you are looking for scaling and rotating methods for image view: These above works fine (with this little change )
Related
I built a simple app that you can pick a photo of yourself, select a border for it and then save it as image. The way I did this is adding 2 ImageViews on top of each other in a parent view. Then converting this parent view to image and save. However with this way, the resulting image size depends on the device screen size. If the device screen is small, a small final image is generated.
What I want is creating an image file with a size of 500x800 pixels at all times regardless of device. What is the correct way to do this?
The preview on the screen could be small, but when I click save button I need it to be exactly 500x800.
First, convert your image to bitmap by :
Bitmap bitmapImage= BitmapFactory.decodeResource(getResources(), R.drawable.large_icon);
Or, if you have Uri of image then use this to convert it to bitmap:
Bitmap bitmap = BitmapFactory.decodeFile(imageUri.getPath());
Both of this will give you a bitmap of your image.
Now to resize your image use this code:
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, imageWidth, imageHeight, true);
Then convert it into File.
To Add to Jason Answer, we found the best way to scale the image, is to use this to scale it up or down.
public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) {
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
// Compute the scaling factors to fit the new height and width, respectively.
// To cover the final image, the final scaling will be the bigger
// of these two.
float xScale = (float) newWidth / sourceWidth;
float yScale = (float) newHeight / sourceHeight;
float scale = Math.max(xScale, yScale);
// Now get the size of the source bitmap when scaled
float scaledWidth = scale * sourceWidth;
float scaledHeight = scale * sourceHeight;
// Let's find out the upper left coordinates if the scaled bitmap
// should be centered in the new size give by the parameters
float left = (newWidth - scaledWidth) / 2;
float top = (newHeight - scaledHeight) / 2;
// The target rectangle for the new, scaled version of the source bitmap will now
// be
RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
// Finally, we create a new bitmap of the specified size and draw our new,
// scaled bitmap onto it.
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
Canvas canvas = new Canvas(dest);
canvas.drawBitmap(source, null, targetRect, null);
return dest;
}
Please try to below code to save bitmap image as custom height & width, Below is a snippet of code that will allow you to resize a Bitmap.
public Bitmap getResizeBitmap(Bitmap bmp, int newHeight, int newWidth) {
int width = bmp.getWidth();
int height = bmp.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// CREATE A MATRIX FOR THE MANIPULATION
Matrix matrix = new Matrix();
// RESIZE THE BIT MAP
matrix.postScale(scaleWidth, scaleHeight);
// RECREATE THE NEW BITMAP
Bitmap resizeBitmap = Bitmap.createBitmap(bmp, 0, 0, width, height, matrix, false);
return resizeBitmap;
}
I'm making a public transportation map based on Google Maps service for Android. The map should contain a lot of markers (over 300) and they should resize when the map is zooming in and out (scale). Right now the markers just overlap each other, is there a way to create custom markers like this?
I have tried myself, but have had no success. With android-map-utils library (https://github.com/googlemaps/android-maps-utils) markers now look better, but they aren't resizeable and look different.
Criteria:
- Markers contain a dot that points on needed location and text on right or left side of dot
- Markers should resize with map.
using bitmapscale
Bitmap markerBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon_marker,options);
markerBitmap = SubUtils.scaleBitmap(markerBitmap, 70, 70);
then set it to your Markeroptions
MarkerOptions marker = new MarkerOptions().icon(BitmapDescriptorFactory.fromBitmap(markerBitmap));
Marker mark = googleMap.addMarker(marker);
EDIT
here is scaleBitmap method
public static Bitmap scaleBitmap(Bitmap bitmap, int newWidth, int newHeight) {
Bitmap scaledBitmap = Bitmap.createBitmap(newWidth, newHeight, Bitmap.Config.ARGB_8888);
float scaleX = newWidth / (float) bitmap.getWidth();
float scaleY = newHeight / (float) bitmap.getHeight();
float pivotX = 0;
float pivotY = 0;
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(scaleX, scaleY, pivotX, pivotY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bitmap, 0, 0, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
I'm having problems while trying to rotate a picture with java android canvas.drawImage. I'm doing a little game, and I'm painting different pictures on the screen using my drawImage function. However now I want to rotate some little images, I have created a function called drawMirroredImage for this. However now this little images don't appear on the same place.
Here is my code:
public void drawImage(Image Image, int x, int y) {
canvas.drawBitmap(((AndroidImage) Image).bitmap, x, y, null);
}
public void drawMirroredImage(Image Image, int x, int y) {
canvas.save();
canvas.scale(-1.0f, 1.0f);
canvas.drawBitmap(((AndroidImage) Image).bitmap, x - canvas.getWidth(), y, null);
canvas.restore();
}
Anyone knows what I'm doing wrong?
Lot of thanks for helping
Following will work for you.
I found it somewhere on SO itself but don't remember where.
public static Bitmap getReflectionedBitmap(Context context,int resourceId,Bitmap originalImage,int reflectionGap) {
if(originalImage==null)
originalImage = BitmapFactory.decodeResource(context.getResources(),resourceId);
int width = originalImage.getWidth();
int height = originalImage.getHeight();
// This will not scale but will flip on the Y axis
Matrix matrix = new Matrix();
matrix.preScale(1, -1);
// Create a Bitmap with the flip matix applied to it.
// We only want the bottom half of the image
Bitmap reflectionImage = Bitmap.createBitmap(originalImage, 0,
height / 2, width, height / 2, matrix, false);
// Create a new bitmap with same width but taller to fit reflection
Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
(height + height / 2), Config.ARGB_8888);
// Create a new Canvas with the bitmap that's big enough for
// the image plus gap plus reflection
Canvas canvas = new Canvas(bitmapWithReflection);
// Draw in the original image
canvas.drawBitmap(originalImage, 0, 0, null);
// Draw in the gap
Paint deafaultPaint = new Paint();
deafaultPaint.setColor(0xffffffff);
canvas.drawRect(0, height, width, height + reflectionGap , deafaultPaint);
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
Paint paint = new Paint();
LinearGradient shader = new LinearGradient(0,
originalImage.getHeight(), 0, bitmapWithReflection.getHeight()
+ reflectionGap, 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
// Set the paint to use this shader (linear gradient)
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
+ reflectionGap, paint);
return bitmapWithReflection;
}
I tweaked the snippet a little bit to use it with resource images as well.
Pass in null as parameter in place of Bitmap if you want to create reflection for images in resource.
I have a 480 x 800 bitmap that I am using for a live wallpaper I am creating. When I test on the emulator the bitmap width and height scales fine but when I test on my Samsung S3 the bitmap width scales fine but the height is too short, shows black rectangle at the bottom. Is there a standard bitmap size I should be working with or is there something wrong in my code?:
public void doDraw(Canvas c) {
c.drawColor(Color.rgb(0,0,0)); // Clear the background.
final int canvasWidth = getScreenWidth();
final int canvasHeight = getScreenHeight();
int imageWidth = mBitmap.getWidth();
int imageHeight = mBitmap.getHeight();
float scaleFactor = Math.min( (float)canvasWidth / imageWidth,
(float)canvasHeight / imageHeight );
Bitmap scaled = Bitmap.createScaledBitmap( mBitmap,
(int)(scaleFactor * imageWidth),
(int)(scaleFactor * imageHeight),
true );
c.drawBitmap(scaled, 0, 0, null);
I think you want Math.max() instead of Math.min()
Is there anyway i could scale an image to become 1.25x bigger everytime a button is pushed?
Basically, could someone give me some tips on how to do this? An explanation, a link, a tutorial, anything would be helpful :) thanks in advance
You should follow this.
http://www.anddev.org/resize_and_rotate_image_-_example-t621.html
Here is code from this page. It creates a Matrix to perform operations(resize and rotate) and applies that matrix to create new BitMap.
You can add the code(with some modifications) on OnClickListener event of yout Button.
public class bitmaptest extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
LinearLayout linLayout = new LinearLayout(this);
// load the origial BitMap (500 x 500 px)
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),
R.drawable.android);
int width = bitmapOrg.width();
int height = bitmapOrg.height();
int newWidth = 200;
int newHeight = 200;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
// createa matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// rotate the Bitmap
matrix.postRotate(45);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,
width, height, matrix, true);
// make a Drawable from Bitmap to allow to set the BitMap
// to the ImageView, ImageButton or what ever
BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);
ImageView imageView = new ImageView(this);
// set the Drawable on the ImageView
imageView.setImageDrawable(bmd);
// center the Image
imageView.setScaleType(ScaleType.CENTER);
// add ImageView to the Layout
linLayout.addView(imageView,
new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT
)
);
// set LinearLayout as ContentView
setContentView(linLayout);
}
}
You can use Bitmap.createScaledBitmap() to resize image.
Refer to my articles on Image Processing to get some idea :): https://xjaphx.wordpress.com/learning/tutorials/