android - 如何从 Android 中的缩放视图中获取位图
问题描述
我有一个名为 MyView 的自定义视图,并正确启用了缩放!用手指缩放视图后,我想得到这个结果视图的位图。为此,我使用下面的 getBitmap () 方法,但它不起作用!它仅在视图未缩放时才有效(scaleFactor = 1.0f)。我用getWidth()/ scaleFactor,getHeight()/ scaleFactor替换了getWidth(),getHeight(),但它也不起作用!
//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;
}
那么如何从缩放视图中获取位图(scaleFactor!= 1.0f)?
更新:包括完整的项目:
//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;
}
}
主要活动
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>
在这个项目中,我创建了三个矩形,一个在窗口内,两个在窗口外,在运行这个项目之前,我在“Bitmap bitmap = myView.getBitmap ();”这一行中添加了一个断点 (主要活动)当应用程序打开时,我缩小窗口,直到所有 3 个矩形出现在窗口中,然后单击按钮查看调试器输出的位图。
奇怪!位图不包括三个矩形,它只是在缩放之前捕获原始窗口中可见的矩形(scaleFactor = 1)。
解决方案
2部分的答案。
- scaleFactor > 1.0f 是放大, scaleFactor < 1.0f 是缩小
所以计算应该是getWidth() * scaleFactor
例如 0.5f 的 scaleFactor 是一半大小
- 您需要的大小是 a
int
并且 scaleFactor 是 afloat
,因此您无法获得所需位图的确切宽度,但应该可以使用四舍五入Math.round()
推荐阅读
- visual-studio - 未找到 OpenCV ALL_BUILDS VS
- android - 多张图像的视差效果滚动
- java - 通过 Groovy 脚本配置 Jenkins Hockeyapp 插件
- java - 重现javaFX焦点效果
- javascript - 对象即使存在也无法访问
- ios - 触摸文本字段时创建操作
- c# - 将一行从一个 ListView 复制到另一个
- javascript - 如何使用 SMTP 在 ionic 3 中发送电子邮件?
- java - Spring - 无法加载资源(CSS)
- android - 无法解析 android.arch.lifecycle:extensions:1.1.0