.:: CODE SNIPPET ::.

"Your time is limited, so don't waste it living someone else's life"

Vẽ màn màn tối bao quanh vùng trên hình ảnh.


Hôm nay mình hướng dẫn cách vẽ một màn tối bao phủ lên một tấm hình. Màn tối chỉ chừa ra một phạm vi là một mình chữ nhật nhỏ nằm tại vị trí nào đó mà bạn muốn. Kiểu như hình sau:

Chắc bạn cũng có thể thấy là việc này dùng trong bài viết trước của mình khi tạo ra một khung bao quanh camera.
Ý nghĩa của việc này là khi bạn cần làm một chuyện gì đó với hình ảnh của mình ví dụ như bạn muốn crop một phần hình ảnh bên trong khung sáng, hoặc bạn muốn che mờ đi các phần xung quanh.
Cách thực hiện của mình là mình sẽ vẽ mỗi thứ lên một view. Cụ thể, mình sẽ vẽ ảnh bên dưới lên một view và sau đó vẽ một màn che phủ lên bên trên lên một view khác.

Cover.java

Đầu tiên chúng ta sẽ tạo một View tên là Cover để vẽ lớp bao phủ. Lớp này kế thừa từ lớp View để có thể thực hiện hành vi vẽ lên màn hình

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.AttributeSet;
import android.view.View;

public class Cover extends View{
	Paint myPaint;
	Rect bigRect;
	Rect smallRect;
	public Cover(Context cont){
		super(cont);
		init(cont);
	}
	public Cover(Context context, AttributeSet attrs){
		super (context,attrs);
		init(context);
	}

	public Cover(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}
	private void init(Context cont){
		bigRect=new Rect(0, 0, MainActivity.scrWidth, MainActivity.scrHeight);
		smallRect=new Rect(50, 50, 100, 200);

		myPaint=new Paint();
		myPaint.setARGB(150,20, 20, 20);
	}
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		canvas.save();
		canvas.clipRect(smallRect,Region.Op.DIFFERENCE);
		canvas.drawRect(bigRect, myPaint);
		canvas.restore();
	}
}

Trong lớp này, chúng ta sẽ Override phương thức onDraw(Canvas) để vẽ lên màn hình. Trong hàm này chú ý đến hàm clipRect, hàm này dùng để tạo ra vùng trống bên trong của lớp phủ mà chúng ta cần.
Điều thú vị trong lớp này là chúng ta tạo ra đến những ba constructor, nhưng chỉ gọi có 1 cái. Nếu bạn bỏ bớt đi thì chương trình sẽ gặp lỗi không thể khởi động:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.testlungtung/com.example.testlungtung.MainActivity}: android.view.InflateException: Binary XML file line #6: Error inflating class com.example.testlungtung.Cover

Lúc đầu viết mình cũng chẳng biết tại sao chương trình không khởi chạy được mà cứ báo lỗi, làm tốn bao nhiêu là thời gian. 🙂

Image.java

Tiếp theo chúng ta sẽ tạo ra một lớp chứa hình ảnh. Lớp này cũng kế thừa từ lớp View. Nó trông như lớp Cover nhưng chỉ khác là vẽ hình ảnh từ Drawable:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;

public class Image extends View{

	private Drawable img;
	private Rect rect;
	public Image(Context context){
		super(context);
		init(context);
	}
	public Image(Context context, AttributeSet attrs){
		super (context,attrs);
		init(context);
	}

	public Image(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}
	private void init(Context cont){
		img=cont.getResources().getDrawable(R.drawable.back);
		rect=new Rect(0, 0, MainActivity.scrWidth, MainActivity.scrHeight);
	}
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		canvas.save();
		img.setBounds(rect);
		img.draw(canvas);
		canvas.restore();
	}
}

activity_main.xml

Giờ chúng ta tạo ra file layout chính để sắp các thứ vào, bao gồm hình ảnh bên dưới và lớp phủ bên trên

<!--?xml version="1.0" encoding="utf-8"?-->
<!--?xml version="1.0" encoding="utf-8"?-->


    <com.example.testlungtung.Cover         android:id="@+id/cover"         android:layout_width="fill_parent"         android:layout_height="fill_parent" />

    <com.example.testlungtung.Image         android:id="@+id/image"         android:layout_width="fill_parent"         android:layout_height="fill_parent"          />


MainActivity.java

Giờ đây là việc còn lại phải làm là viết activity chính của chương trình, cho mọi thứ hoạt động

import android.os.Bundle;
import android.app.Activity;
import android.util.DisplayMetrics;
import android.view.View;

public class MainActivity extends Activity {

	public static int scrWidth;
	public static int scrHeight;
	private Cover cover;
	private Image img;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        DisplayMetrics displaymetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
		scrHeight = displaymetrics.heightPixels;
		scrWidth = displaymetrics.widthPixels;
		setContentView(R.layout.activity_main);

		cover=(Cover)findViewById(R.id.cover);
		img=(Image)findViewById(R.id.image);
		img.invalidate();
		cover.invalidate();

		cover.bringToFront();

		cover.setVisibility(View.VISIBLE);
		img.setVisibility(View.VISIBLE);
    }

}

Ở đây, chúng ta có các công việc là: sử dụng hàm invalidate() để cho các View thực hiện hành vi Vẽ (onDraw) lên màn hình, hàm bringToFront() để đưa phần màn bao phủ lên trên view hình ảnh.
Thế là xong

Advertisements

One response to “Vẽ màn màn tối bao quanh vùng trên hình ảnh.

  1. future garage November 18, 2012 at 12:12 AM

    Hey my name is June and I’m a student and this website really helped me. I’m refocused! Thank you!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: