2013-07-08 1 views
29

У меня есть короткий вопрос:Как сделать любой вид рисовать на холст?

Предположим, у меня есть (изменяемый) растровый рисунок, который мне нужно изменить (добавить изображения, тексты и т. Д.).

Вместо того, чтобы возиться со многими специальными классами для рисования на холсте (краска, холст, матрицы и т. Д.), Я думал, почему бы не использовать встроенные классы 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); 
} 

такая вещь возможна? возможно, это даже то, как он работает за кулисами?

Что я должен писать в части между рисунком и созданием холста?


EDIT: я попытался следующий код, но он не работает:

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); 

EDIT: есть образец на sony's website:

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); 

интересно, работает ли оно.

ответ

44

Да, вы можете это сделать. Имейте в виду, так как вы не приложив ее к макету, вам нужно положить его вручную перед рисованием:

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()); 

EDIT:

Если вы уже знаете, ширину и высоту, вам необходимо:

//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(); 

EDIT еще раз:

Да, проверено. Вы можете попробовать это:

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); 
    } 
} 
+0

Прямоугольник, о котором я упоминал, следует использовать для ширины и высоты, на которые разрешено рисовать. могу ли я использовать его ширину и высоту? также, где находится часть, которая обращается к месту расположения прямоугольника? –

+0

Если вы уже знаете местоположение и размер, это намного проще. См. Редактирование. – kcoppock

+0

Вы уверены, что это работает? вы пробовали это, например, в textView или imageView? –

 Смежные вопросы

  • Нет связанных вопросов^_^