I have a custom view named MyView with scaling correctly enabled, After scaling the view using fingers. I want to get a Bitmap of this resulting View, For that I use the getBitmap () method below. but it doesn't work. it only works if the view is not scaled (scaleFactor = 1,0f), I replaced getWidth (), getHeight () with getWidth () / scaleFactor, getHeight () / scaleFactor but it doesn't work either!
//These two methods are inside the MyView class
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(scaleFactor, scaleFactor);
canvas.drawPath(path, paint);
canvas.restore();
}
public Bitmap getBitmap(){
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
draw(canvas);
return bitmap;
}
So how do I get a bitmap from the scaled view (scaleFactor.= 1?0f)?
UPDATE: include full project:
//myview
public class MyView extends View {
private Path path;
private Paint paint;
private ScaleGestureDetector scaleDetector;
private float scaleFactor = 1.0f;
public MyView(Context context) {
super(context);
init(context);
}
public MyView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context){
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
path = new Path();
//inside window
path.addRect(300, 300, 600, 600, Path.Direction.CW);
//outside window
path.addRect(800, 800, 1000, 1000, Path.Direction.CW);
//outside window
path.addRect(1000, 1000, 1200, 1200, Path.Direction.CW);
scaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(scaleFactor, scaleFactor);
canvas.drawPath(path, paint);
canvas.restore();
}
public Bitmap getBitmap(){
Bitmap bitmap =
Bitmap.createBitmap(
Math.round(getWidth()*scaleFactor),
Math.round(getHeight()*scaleFactor),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
draw(canvas);
return bitmap;
}
private class ScaleListener
extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
scaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 5f));
invalidate();
return true;
}
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
// Let the ScaleGestureDetector inspect all events.
scaleDetector.onTouchEvent(ev);
return true;
}
}
Main activity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyView myView = findViewById(R.id.my_view);
Button button = findViewById(R.id.button);
button.setOnClickListener(view -> {
Bitmap bitmap = myView.getBitmap(); //add breakpoint in this line
int width = bitmap.getWidth();
int height = bitmap.getHeight();
});
}
}
xml
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.abdo.scaledviewtobitmapquestion.MyView
android:id="@+id/my_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:text="Hello World!"
app:layout_constraintBottom_toTopOf="@id/button"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Bitmap"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
In this project I am creating three rectangles, one inside the window and two outside the window, Before running this project I added a breakpoint in this line "Bitmap bitmap = myView.getBitmap ();" (The main activity) When the app is open, I zoom out the window until all 3 rectangles appear in the window, then click the button to see the bitmap of the debugger output.
Surprising, The bitmap does not include the three rectangles. it just captures the rectangle visible in the original window before scaling (scaleFactor = 1).
2 parts to the answer.
So the calculation should be getWidth() * scaleFactor
eg scaleFactor of 0.5f is half size
int
and scaleFactor is a float
, so you cannot get and exact width of the required bitmap though should be OK to round up using Math.round()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.