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;
}
Related
I'm trying to draw some text on bitmap with a fixed position (Bottom left corner) no matter how bitmap size different.
Code below works but, the Text is drawn on the center of the bitmap
public Bitmap drawTextToBitmap(Context gContext,
Bitmap bitmap,
String gText) {
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
android.graphics.Bitmap.Config bitmapConfig =
bitmap.getConfig();
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(getResources().getColor(R.color.fujiColor));
paint.setTypeface(Typeface.createFromAsset(getAssets(), "fonts/DS-DIGI.TTF"));
paint.setTextSize((int) (14 * scale));
paint.setShadowLayer(1f, 0f, 1f, getResources().getColor(R.color.fujiShadowColor));
Rect bounds = new Rect();
paint.getTextBounds(gText, 0, gText.length(), bounds);
int x = (bitmap.getWidth() - bounds.width()) / 2;
int y = (bitmap.getHeight() + bounds.height()) / 2;
canvas.drawText(gText, x, y, paint);
return bitmap;
}
What I need is something similar to this :
Thank you.
As mentioned in the official docs, the text is drawn taking the (x,y) values as origin. Change the x,y values. Something along the following lines should work.
int horizontalSpacing = 24;
int verticalSpacing = 36;
int x = horizontalSpacing;//(bitmap.getWidth() - bounds.width()) / 2;
int y = bitmap.getHeight()-verticalSpacing;//(bitmap.getHeight() + bounds.height()) / 2;
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 am a beginner in Android, I need your help for understanding what this code is actually doing. As I am unable to get its purpose, and I am unable to get why we are using matrix and canvas in this:
My Java Code
float ratioX = actualWidth / (float) options.outWidth;
float ratioY = actualHeight / (float) options.outHeight;
float middleX = actualWidth / 2.0f;
float mieX));
Log.d("middleY",String.valueOf(middleY));
Matrix scaleMatrix = new Matrix();
scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);
Canvas canvas = new Canvas(scaledBitmap);
canvas.setMatrix(scaleMatrix);
canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));
Canvas == View
All Views in Android uses Canvas/ViewPort to draw it's visible content. The Matrix is in simplicity the current drawing board for the Canvas.
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'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 )