web-dev-qa-db-ja.com

キャンバスに描画するビューを作成する方法は?

短い質問があります:

変更(イメージ、テキストなどの追加)が必要な(可変)ビットマップがあるとします。

キャンバスに描画するための多くの特別なクラス(ペイント、キャンバス、マトリックスなど)をいじるのではなく、Androidこのタスクにのみ本当にカスタマイズされた操作が必要な場合、キャンバスを使用できますか?

したがって、たとえば、ビットマップ上に任意の種類のビュー(もちろん、親のないビュー)を表示するには、次の関数を呼び出すことができます。

public void drawViewToBitmap(Bitmap b, View v, Rect rect) {
    Canvas c = new Canvas(b);
    // <= use rect to let the view to draw only into this boundary inside the bitmap
    view.draw(c);
}

そのようなことは可能ですか?多分それは舞台裏で動作する方法ですか?

描画とキャンバスの作成の間の部分に何を書くべきですか?


編集:私は次のコードを試しましたが、うまくいきませんでした:

public void drawFromViewToCanvas(final View view, final Rect rect, final Canvas canvas) {
    final int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);
    final int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);
    view.measure(widthSpec, heightSpec);
    // Lay the view out with the known dimensions
    view.layout(0, 0, rect.width(), rect.height());
    // Translate the canvas so the view is drawn at the proper coordinates
    canvas.save();
    canvas.translate(rect.left, rect.top);
    // Draw the View and clear the translation
    view.draw(canvas);
    canvas.restore();
}

使用例:

final int imageSize = 50;
rect = new Rect(35, 344 , 35 + imageSize, 344  + imageSize);
final ImageView imageView = new ImageView(mContext);
imageView.setImageBitmap(bitmap);
imageView.setScaleType(ScaleType.CENTER_CROP);
drawFromViewToCanvas(imageView, getRect(), canvas);

編集: sonyのWebサイト にサンプルがあります:

int measureWidth = View.MeasureSpec.makeMeasureSpec(bitmapWidth, View.MeasureSpec.EXACTLY);
int measuredHeight = View.MeasureSpec.makeMeasureSpec(bitmapHeight, View.MeasureSpec.EXACTLY);
view.measure(measureWidth, measuredHeight);
view.layout(0, 0, bitmapWidth, bitmapHeight);
view.draw(canvas);

それが機能するかどうか疑問に思う。

36

ええ、あなたはこれを行うことができます。レイアウトに添付していないため、描画する前に手動でレイアウトする必要があることに注意してください。

view.layout(0, 0, viewWidth, viewHeight);

そして、これらの幅と高さのパラメーターに何が必要かを正確に把握していない限り、最初にそれを測定することもできます。

int widthSpec = MeasureSpec.makeMeasureSpec (ViewGroup.LayoutParams.WRAP_CONTENT, MeasureSpec.UNSPECIFIED;
int heightSpec = MeasureSpec.makeMeasureSpec (400, MeasureSpec.UNSPECIFIED;
view.measure(widthSpec, heightSpec);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

編集:

幅と高さがすでにわかっている場合は、次が必要です。

//Lay the view out with the known dimensions
view.layout (0, 0, rect.width(), rect.height());

//Translate the canvas so the view is drawn at the proper coordinates
canvas.save();
canvas.translate(rect.left, rect.top);

//Draw the View and clear the translation
view.draw(canvas);
canvas.restore();

もう一度編集:

はい、テスト済み。あなたはこれを自分で試すことができます:

public class DrawingActivity extends Activity {
    public void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Set a Rect for the 200 x 200 px center of a 400 x 400 px area
        Rect rect = new Rect();
        rect.set(100, 100, 300, 300);

        //Allocate a new Bitmap at 400 x 400 px
        Bitmap bitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);

        //Make a new view and lay it out at the desired Rect dimensions
        TextView view = new TextView(this);
        view.setText("This is a custom drawn textview");
        view.setBackgroundColor(Color.RED);
        view.setGravity(Gravity.CENTER);

        //Measure the view at the exact dimensions (otherwise the text won't center correctly)
        int widthSpec = View.MeasureSpec.makeMeasureSpec(rect.width(), View.MeasureSpec.EXACTLY);
        int heightSpec = View.MeasureSpec.makeMeasureSpec(rect.height(), View.MeasureSpec.EXACTLY);
        view.measure(widthSpec, heightSpec);

        //Lay the view out at the rect width and height
        view.layout(0, 0, rect.width(), rect.height());

        //Translate the Canvas into position and draw it
        canvas.save();
        canvas.translate(rect.left, rect.top);
        view.draw(canvas);
        canvas.restore();

        //To make sure it works, set the bitmap to an ImageView
        ImageView imageView = new ImageView(this);
        imageView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        setContentView(imageView);
        imageView.setScaleType(ImageView.ScaleType.CENTER);
        imageView.setImageBitmap(bitmap);
    }
}
57
kcoppock