Cách thêm hiệu ứng cho hình ảnh.
Bài đăng này đã không được cập nhật trong 9 năm
Chào các bạn, vậy là đã hết 1 tháng ngắn ngủn, một tháng khá là bận rộn, tất bật. Chắc hẳn các bạn cũng tôi vậy. Nhưng cũng không phải vì vậy mà lại quên đi nhiệm vụ của mình là học tập. Học tập không ngừng nghỉ. Đùa vậy chứ bản thân mình thì chơi là nhiều.
Hôm nay xin được chia sẻ với các bạn một tut nho nhỏ về làm thế nào để có thể add effect cho ảnh. Thật ra thì các bạn cũng có thể search trên mạng hiện nay đã có rất nhiều rồi. Nhưng tại sao mình lại tìm hiểu về nó? À đơn giản thì là mình chưua biết tới nó. Nếu bạn đọc đã biết về nó rồi, kính mong được chỉ giáo thêm hoặc chỗ nào mình hiểu sai. Còn bạn nào chưua biết, muốn mình support gì thì có thể liên hệ nhé. Nào giờ thì let's go ! Tất nhiên việc trước tiên chúng ta cần làm là tạo một project mới. Ở đây tôi tạo như hình dưới.! Screen Shot 2015-05-28 at 22.53.14.png
Tiếp chúng ta sẽ sửa layout main_activity.xml như sau:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="@+id/gallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Chọn hình " />
<ImageView
android:id="@+id/original_image"
android:layout_width="fill_parent"
android:layout_height="300dp"
android:layout_marginTop="20dp" />
<Button
android:id="@+id/effects_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:text="Thêm Effect" />
</LinearLayout>
Tạo thêm một file xml(ở đây tôi đặt name là: list_of_effects.xml) với nội dung như sau:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="20sp"
android:background="#cd6959">
</TextView>
Tạo tiếp một file final_view.xml với nội dung:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="20dp" />
</LinearLayout>
Tại sao một lúc lại tạo liền 2 file .xml thế này để làm gì, bạn nào biết rồi thì đừng nói vội nhé, để cho các bạn chưa biết thêm phần tò mò đuê.
Code mấy cái event cho MainActivity.java nhé:
package com.framgia.effectimg;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends ActionBarActivity {
Button gallery;
Bitmap image;
ImageView originalIMG;
Button addEffects;
String picturePath;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
originalIMG = (ImageView) findViewById(R.id.original_image);
addEffects = (Button) findViewById(R.id.effects_btn);
gallery = (Button) findViewById(R.id.gallery);
gallery.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// khi click vào btn gallery thì mở ra để chọn ảnh
Intent intent = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 1);
}
});
addEffects.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, ListOfEffects.class);
i.putExtra("imgPath", picturePath);
startActivity(i);
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
Uri selectedImage = data.getData();
String[] filePath = { MediaStore.Images.Media.DATA };
Cursor c = getContentResolver().query(selectedImage, filePath,
null, null, null);
c.moveToFirst();
int columnIndex = c.getColumnIndex(filePath[0]);
picturePath = c.getString(columnIndex);
c.close();
image = (BitmapFactory.decodeFile(picturePath));
originalIMG.setImageBitmap(image);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Code này chắc chắn có lỗi, bởi vì chúng ta chưa có Class ListOfEffects. Vì tut này tôi muốn hướng dẫn phát là xong ngay chứ không code file này xong lại nhảy sang file kia xong lại về code file này. Vậy nên các bạn chịu khó cùng tôi đi hết từng file 1 nhé. :3
Tạo class ListOfEffects.java nào:
package com.framgia.effectimg;
import java.util.ArrayList;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class ListOfEffects extends ListActivity {
ArrayList<String> effectsList = new ArrayList<String>();
String path;
String effectSelected;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i = getIntent();
path = i.getStringExtra("imgPath");
effectsList.add("Eff 1");
effectsList.add("Eff 2 ");
effectsList.add("Eff 3");
effectsList.add("Eff 4");
effectsList.add("Eff 5");
// sét danh sách menu effect để chọn
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_of_effects,
effectsList));
ListView listView = getListView();
listView.setTextFilterEnabled(true);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// commit luôn eff
effectSelected = effectsList.get(position);
commitEffects();
}
});
}
// commit effect
void commitEffects() {
Intent i = new Intent(ListOfEffects.this, EffectAdded.class);
i.putExtra("path", path);
i.putExtra("effect", effectSelected);
startActivity(i);
}
}
Sắp xong rồi, phù. Tạo thêm class EffectAddeds.java
package com.framgia.effectimg;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.util.Log;
import android.widget.ImageView;
public class EffectsAdded extends Activity {
String path;
String effectSelect;
ImageView changed;
Bitmap out;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.final_view);
Intent i = getIntent();
path = i.getStringExtra("path");
effectSelect = i.getStringExtra("effect");
changed = (ImageView) findViewById(R.id.view);
Bitmap thumbnail = (BitmapFactory.decodeFile(path));
if (effectSelect.equalsIgnoreCase("Eff 1")) {
out = addEffect(thumbnail, 5, 5.0, 6.0, 0.0);
} else if (effectSelect.equalsIgnoreCase("Eff 2")) {
out = addEffect(thumbnail, 5, 5.0, 0.0, 10.0);
} else if (effectSelect.equalsIgnoreCase("Eff 3")) {
out = addEffect(thumbnail, 5, 0.0, 10.0, 0.0);
} else if (effectSelect.equalsIgnoreCase("Eff 4")) {
out = addEffect(thumbnail, 15, 5.0, 0.0, 10.0);
} else if (effectSelect.equalsIgnoreCase("Eff 5")) {
out = addEffect(thumbnail, 5, 10.0, 0.0, 0.0); // only red
}
changed.setImageBitmap(out);
}
// xử lý hình ảnh
public static Bitmap addEffect(Bitmap src, int depth, double red,
double green, double blue) {
int width = src.getWidth();
int height = src.getHeight();
Bitmap finalBitmap = Bitmap
.createBitmap(width, height, src.getConfig());
final double grayScale_Red = 0.3;
final double grayScale_Green = 0.59;
final double grayScale_Blue = 0.11;
int channel_aplha, channel_red, channel_green, channel_blue;
int pixel;
for (int x = 0; x < width; ++x) {
for (int y = 0; y < height; ++y) {
pixel = src.getPixel(x, y);
channel_aplha = Color.alpha(pixel);
channel_red = Color.red(pixel);
channel_green = Color.green(pixel);
channel_blue = Color.blue(pixel);
channel_blue = channel_green = channel_red = (int) (grayScale_Red
* channel_red + grayScale_Green * channel_green + grayScale_Blue
* channel_blue);
channel_red += (depth * red);
if (channel_red > 255) {
channel_red = 255;
}
channel_green += (depth * green);
if (channel_green > 255) {
channel_green = 255;
}
channel_blue += (depth * blue);
if (channel_blue > 255) {
channel_blue = 255;
}
finalBitmap.setPixel(x, y, Color.argb(channel_aplha,
channel_red, channel_green, channel_blue));
}
}
return finalBitmap;
}
}
Còn thiếu gì nữa nhỉ? Còn phải fix thêm trong file AndroidM anifest.xml nữa. Cái này với ai đã làm quen với android rồi thì có thể làm trong vài second. Còn với bạn mới hay bắt đầu thì có thể là chưa nên các bạn tự config file này đi cho quen nhé.
Mấy đoạn code xử lý ảnh mình cũng chỉ tham khảo trên mạng thôi nên xử lý hơi chậm. Bạn đọc có cách nào thì chỉ cho mình nhé. Trên đây chỉ là demo cái mình tìm hiểu.
All rights reserved