I have a bitmap thumbnail for a map and I want to add the a map marker in the center but am struggling to do so. I was able to overlay the two bitmaps but the the one in front is significantly smaller and not centered. Is there a way to center the bitmap and scale it up? This is what it looks like:
I looked at this Android: How to overlay-a-bitmap/draw-over a bitmap? and it helped but the map marker is very small and off centered. Thanks
Update:
I ended up solving it this way. I'll leave my solution for anyone who needs it in the future. Here it goes:
public static Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bmp2, 500, 500, false);
Bitmap bitmapWithOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bitmapWithOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(resizedBitmap, ((bmp1.getWidth()/2)-250), ((bmp1.getHeight()/2)-450), null);
return bitmapWithOverlay;
}
and here is the process of getting the bitmap from a drawable
Bitmap icon = BitmapFactory.decodeResource(getActivity().getBaseContext().getResources(),
R.drawable.your_icon);
You can put both in the same FrameLayout. FrameLayout is build to only have one child, if you put more childs into it they will overlap. Ty this.
And also putting more childs into FrameLayout isn't bad practice.
Related
I have a method for screenshot which takes the View from XML and convert to Bitmap object, and I have multiple PNG on layout View. Some PNG have transparent Area which appears as Black color in Bitmap (which i want to change to White) or want to get rid of Black transparent area.
private void takescreenshot(LinearLayout preview) throws IOException
{
View z = preview; // get whole layout view
z.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(z.getDrawingCache());
z.destroyDrawingCache();
}
create a new blank bitmap
create canvas object
fill the canvas a background
put old bitmap in your canvas.
Bitmap newBitmap = Bitmap.create(bitmap.width,bitmap.height,ARGB_8888)
Canvas canvas = new Canvas(newBitmap)
canvas.drawColor(Color.white)
canvas.drawBitmap(bitmap,0F,0F,null)
finally i figure out the solution as well
View z = preview; // get whole layout view
z.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(z.getDrawingCache());
z.destroyDrawingCache();
Bitmap newBitmap = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(),ARGB_8888);
newBitmap.eraseColor(Color.WHITE);
Canvas canvas2 = new Canvas(newBitmap);
canvas2.drawBitmap(bitmap,0F,0F,null);
I'm making an app that cuts a circle shape from a large image and saves it as a thumbnail.
To do this I have created a FrameLayout to enclose an ImageView and a CustomView whose dimensions match the parent. Glide is used to load the image into the ImageView. And the custom view which sits on top of the imageview has onclick methods that allow a user to drag a scalable circle around the image.
<FrameLayout
android:layout_width="357dp"
android:layout_height="247dp"
android:layout_marginStart="16dp"
android:layout_marginTop="20dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/textView">
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--app:srcCompat="#android:drawable/btn_star_big_on" />-->
<com.example.christopher.thumbnailtest.ThumbnailFrame
android:id="#+id/ThumbnailFrame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
Currently, I am trying to create a bitmap that is the exact same size as the ImageView.
public void cropImage(View view) {
ImageView image = (ImageView) findViewById(R.id.imageView);
BitmapDrawable drawable = (BitmapDrawable) image.getDrawable();
Bitmap bitmap = drawable.getBitmap();
Log.d("bitmap", bitmap.toString());
//Create a bitmap with the same dimensions (thumbnail)
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Log.d("BITMAP_WIDTH", String.valueOf(bitmap.getWidth()));
Log.d("BITMAP_Height", String.valueOf(bitmap.getHeight()));
//Create new canvas with our bitmap to draw into
Canvas canvas = new Canvas(output);
//Set a paint object for a solid colored object
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(0XFF000000);
//Get a handle on current image object
ThumbnailFrame thumbnail = findViewById(R.id.ThumbnailFrame);
//Draw a small circle on the new bitmap (thumbnail) with the same dimensions as that of our thumbnail frame.
canvas.drawCircle(thumbnail.getyPosit(), thumbnail.getxPosit(), thumbnail.getradius(), paint);
Log.d("XPOSIT", String.valueOf(thumbnail.getxPosit()));
Log.d("YPOSIT", String.valueOf(thumbnail.getyPosit()));
Log.d("RADIUS", String.valueOf(thumbnail.getradius()));
//Use Porter.Duff method to make picture ONLY exist in a new bitmap
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//Crop new bitmap with createBitmap
canvas.drawBitmap(bitmap, 0, 0, paint);
//Compress? and save new bitmap as a thumbnail, and send thumbnail URI
}
Sadly, the image which comes back is not the same size as the frame and on certain images the bitmap size changes. When a star shape was originally loaded is was 150 x 150, for this particular image it is (988 x 988) but the dimensions of the imageview should extend past that and are rectangular not square.
D/bitmap: android.graphics.Bitmap#491f236
D/BITMAP_WIDTH: 988
D/BITMAP_Height: 988
D/XPOSIT: 1378.0
D/YPOSIT: 938.0
D/RADIUS: 50.0
Is there a method to get an exact bitmap version of an imageView which is the exact same size?
Note: It doesn't need to be scaled to the dimensions of the imageview, but the bitmap should be the exact same size perhaps filling the extra space with alpha channel.
After doing further research, I learned that you should never use
image.buildDrawingCache(); or Bitmap bmap = image.getDrawingCache();
These are deprecated methods now and the result for me was a distorted image that was only partially loaded.
If you are trying to do what I did, convert the position of the circle in your picture to the measurements of the bitmap. This can be easily done, especially if your imageview is particularly square
[( x coord. of circle) / (imageview width)] * [bitmap width]
using...
BitmapDrawable drawable = (BitmapDrawable) image.getDrawable();
Bitmap bmap = drawable.getBitmap();
If you are trying to take a screen shot of your image view, there is PixelCopy(), I have no idea how to use it but it is documented on the website.
https://developer.android.com/reference/android/view/PixelCopy
I basically have an ImageView which got modified with Canvas and looks like a cirlce. (original image had the dimensions of a square (500x500))
Image what the starting position looks like:
http://imgur.com/bvXdLoP
(red is transparent and got removed with help of the Canvas method)
The animation should take aroud 1000 miliseconds and during this time step for step restore to the original picture. So in the end there should be a sqaure again.
In other words the cut off corners, which are the differnce between a square and a circle (and red marked in the image), get step for step restored in around 1000 milliseconds, with a sort of spreading looking animation.
Don't really have any clue on how to achieve this, so I can just share the Canvas method I used to cut off the corners (if it helps :X):
private Bitmap createCircleImage(Bitmap bitmap) {
Bitmap bmp;
bmp = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bitmap,
BitmapShader.TileMode.CLAMP,
BitmapShader.TileMode.CLAMP);
float radius = bitmap.getWidth() / 2f;
Canvas canvas = new Canvas(bmp);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(shader);
canvas.drawCircle(bitmap.getWidth()/2,bitmap.getHeight()/2,bitmap.getHeight()/2, paint);
return bmp;
}
Appreciate any help,
thank you!
There are many ways to achieve such behavior. For example you can create custom view and override its onDraw method such as
#Override
public void onDraw(Canvas canvas) {
canvas.drawCircle(viewWidth/2, viewHeight/2, currentRadius, paint);
}
and then you can just increase the radius little by little and invalidate the view.Since view is by default will clip on its clipBounds (you can only draw inside viewidth x viewheight rectangle unless you set it otherwise) you will get the effect that you want. And then you can tweak the interpolation to achieve smoother and more natural animation.
note: a bitmap shader is attached to the paint (you already know chow to create it). I don't include it in the code, since you shouldn't initialize it inside onDraw method for performance reason.
I want to display an image on screen (I have an activity that displays an image):
Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
ExifInterface exif = new ExifInterface(imagePath);
int rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
int rotationInDegrees = exifToDegrees(rotation);
Matrix matrix = new Matrix();
matrix.preRotate(rotationInDegrees);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
The last line throws java.lang.OutOfMemoryError
I don't understand how to do this... I have to create the bitmap at first (BitmapFactory.decodeFile) but when I want to rotate it I have to provide the source bitmap already - how can I avoid it?
Thanks
You can try downsizing the image first before decoding it by adding inSampleSize in the bitmap options. as stated at the document: http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html#inSampleSize
If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 5;
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
Hope that helps.
If you aren't doing any crazy things elsewhere then your image is probably just too big.
You just need to increase your heap. Add this to your manifest file:
android:largeHeap="true"
You cannot rotate the bitmap in place, because the dimensions can be different. I don't know, why it's impossible to load already rotated bitmap.
You can rotate the bitmap in the place of use. When drawing the bitmap, use the rotation matrix to have it drawn with rotation.
Other thing is that you probably should review your app and try to minimize the memory usage. Maybe the bitmaps you use are too big and you should use Options with inSampleSize set to 2 or more.
I'm developing an Android application and I would like to blend Bitmap with a filter like "Multiply" or "Difference" from Photoshop. Bitmap1 is translating horizontally and Bitmap2 vertically.
I had few ideas :
1) Create a method which do some calculation to find the intersection part of the two Bitmap (Requires to cross 2 matrix every frame, very heavy, seems impossible ?). Then crop the intersection on the 2 Bitmap, blend them, and finally draw it. Another idea would be to do a ANDing between the two Bitmap, maybe faster than the other method, does thi function already exist ?
2) OpenGL ES ? But I really don't understand how to use it.
3) But recently I have found this sample code which blend two Bitmap on a canvas and use a paint. The result is the one I want BUT there is still no animation. So I've create a new Class (extends View) in addition to this activity, with the method onDraw(Canvas canvas).
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compo);
Bitmap bm1 = BitmapFactory.decodeResource(getResources(), R.drawable.bm1);
Bitmap bm2 = BitmapFactory.decodeResource(getResources(), R.drawable.bm2);
blend(bm1,bm2);
}
private void blend(Bitmap bm1, Bitmap bm2){
DisplayMetrics metrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int h = metrics.heightPixels;
int w = metrics.widthPixels;
/// BLEND MODE ///
// Create result image
Bitmap.Config conf = Bitmap.Config.ARGB_8888; // see other conf types
Bitmap result = Bitmap.createBitmap(w, h, conf);
Canvas canvas = new Canvas();
canvas.setBitmap(result);
// Get proper display reference
BitmapDrawable drawable = new BitmapDrawable(getResources(), result);
ImageView imageView = (ImageView)findViewById(R.id.photo1);
imageView.setImageDrawable(drawable);
// Draw base
canvas.drawBitmap(bm2, 0, 0, null);
// Draw overlay
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));
paint.setShader(new BitmapShader(bm1, TileMode.CLAMP, TileMode.CLAMP));
canvas.drawRect(700, 700, bm2.getWidth(), bm2.getHeight(), paint);
}
Here is the result with changing the value in 'canvas.drawRect()' :
Before translation
After translation
Do you have other solutions ? Or suggestions which would help to realize my filter on animate views ? (The perfect solutions would be to add something like android:blendMode="Multiply" in the XML, but it doesn't seem as easy)
Thank you in advance. J'.