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
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 have a text view with icon rendered in the TextView. It has an image. I have set on the left of the text. But I need to set the icon as a circular shape.
How can I design this in java?
My code which set on the left side.
textview.setCompoundDrawablesWithIntrinsicBounds(
image, 0, 0, 0);
How can I design the circular image for the above textview drawableleft image.
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="fill_vertical"
android:ellipsize="end"
android:layout_marginTop="5dp"
android:layout_marginBottom="-10dp"
android:gravity="center"
android:layout_marginLeft="15dp"
android:minHeight="24dp"
android:paddingLeft="#dimen/spacing_d2"
android:paddingRight="#dimen/spacing_d2"
android:tag="#string/tag_font_h_regular"
android:fontFamily="#font/cachetbook"
android:textColor="#color/white_new"
android:textSize="12dp"
tools:text="Universal Orlando Resort"/>
Load your image
You need to load your image as a bitmap. If you are taking if from your drawable, you can see How to convert a Drawable to a Bitmap?.
Resize it
You can resize your bitmap to scale it to fit your textview as you wish. See How to Resize a Bitmap in Android?.
Make the corner rounded
According to this post you can found the code to make corner rounded
Code example
// Load your drawable
Drawable drawable = ContextCompat.getDrawable(this,R.drawable.ic_launcher_background);
// Convert it to a bitmap
Bitmap bitmap = Bitmap.createScaledBitmap(drawableToBitmap((drawable)),50,50,false);
// Make the corner rounded
RoundedBitmapDrawable roundedBitmapDrawable = RoundedBitmapDrawableFactory.create(getResources(), bitmap);
final float roundPx = (float) bitmap.getWidth() * 90f;
roundedBitmapDrawable.setCornerRadius(roundPx);
// Apply it to the TextView
((TextView) findViewById(R.id.test)).setCompoundDrawablesWithIntrinsicBounds(
roundedBitmapDrawable, null, null, null);
Output
Note
I do not know why you decided to choose to do it programmatically, but I would not recommand it, it is harder to control the view and how things are positionned.
I have transparent images like shapes,letters which I'm fetch from gallery so I need to give them stroke/outline with black color, I can set border but It's set to whole bitmap like left,right,top and bottom.
Same thing we can do with photoshop is giving outerstroke to image but I want to achieve that in android.
I tried this and this It's give border, But what I want to do is like below
sample image
Original Image
I want like this -->
Does this possible in android?
I have an temporary solution like this
int strokeWidth = 8;
Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.flower_icon);
Bitmap newStrokedBitmap = Bitmap.createBitmap(originalBitmap.getWidth() + 2 * strokeWidth, originalBitmap.getHeight() + 2 * strokeWidth, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newStrokedBitmap);
float scaleX = newStrokedBitmap.getWidth() / originalBitmap.getWidth();
float scaleY = newStrokedBitmap.getHeight() / originalBitmap.getHeight();
Matrix matrix = new Matrix();
matrix.setScale(scaleX, scaleY);
canvas.drawBitmap(originalBitmap, matrix, null);
canvas.drawColor(Color.WHITE, PorterDuff.Mode.SRC_ATOP); //Color.WHITE is stroke color
canvas.drawBitmap(originalBitmap, strokeWidth, strokeWidth, null);
Firstly create a new bitmap with stroke size on left, right, bottom and top.
Secondly a little bit scale bitmap and draw scaled bitmap on newly created bitmap canvas.
Draw a color (your stroke color) with PorterDuff mode SRC_ATOP override original bitmap position with stroke color.
Finally draw your original bitmap on newly create bitmap canvas.
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.
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'.