android自定义滤镜,【Android】自定义View那点事(三)ColorFilter篇
前言
前面學習Xfermode的使用,我們可以自定義各種不同樣式的View,本節我們學習關于顏色處理相關的內容。現在很多圖片處理軟件都具有濾鏡功能,選擇不同風格濾鏡可以改變圖片色彩呈現不同風格。Android開發文檔中提供了相應的API供開發者使用,這樣我們自己可以實現圖片濾鏡效果。這節我們主要講ColorMatrixColorFilter,ColorMatrixColorFilter通過ColorMatrix設置4*5的矩陣變換RGBA參數調整顏色。
色彩科普
在開始如何調整圖片顏色之前,我們先了解一下關于色彩方面的知識。Ps:理論知識來源于度娘
色相
色相是色彩的首要特征,是區別各種不同色彩的最準確的標準。事實上任何黑白灰以外的顏色都有色相的屬性,而色相也就是由原色、間色和復色來構成的。色相,色彩可呈現出來的質地面貌。自然界中各個不同的色相是無限豐富的,如紫紅、銀灰、橙黃等。色相即各類色彩的相貌稱謂。
色調
色調指的是一幅畫中畫面色彩的總體傾向,是大的色彩效果。這種在不同顏色的物體上,籠罩著某一種色彩,使不同顏色的物體都帶有同一色彩傾向,這樣的色彩現象就是色調。
灰度
灰度使用黑色調表示物體,即用黑色為基準色,不同的飽和度的黑色來顯示圖像。 每個灰度對象都具有從 0%(白色)到100%(黑色)的亮度值。使用黑白或灰度掃描儀生成的圖像通常以灰度顯示。
對比度
對比度指的是一幅圖像中明暗區域最亮的白和最暗的黑之間不同亮度層級的測量,差異范圍越大代表對比越大,差異范圍越小代表對比越小,好的對比率120:1就可容易地顯示生動、豐富的色彩,當對比率高達300:1時,便可支持各階的顏色。但對比率遭受和亮度相同的困境,現今尚無一套有效又公正的標準來衡量對比率,所以最好的辨識方式還是依靠使用者眼睛。
飽和度
飽和度可定義為彩度除以明度,與彩度同樣表征彩色偏離同亮度灰色的程度。注意,與彩度完全不是同一個概念。但由于其和彩度決定的是出現在人眼里的同一個效果,所以才會出現視彩度與飽和度為同一概念的情況。
主角ColorMatrix
ColorMatrix通過設置4*5的矩陣數值改變圖片的顏色和透明度。我們來看看官方文檔的描述。No picture,say the JJ,來上圖。
Paste_Image.png
可以看到4*5矩陣每一行的運算結果分別代表RGBA的最終的數值,以及它們取值范圍在0-255之間。而每一行最后一個數值代表偏移量,例如想讓R增加100偏移量,則將矩陣數組第四個數值設置為100。
ColorMatrix的reset()方法可以看到,顏色矩陣RGBA的初始情況。
Paste_Image.png
美圖濾鏡效果
原圖
Paste_Image.png
|1,0,0,0,0|
|0,1,0,0,0|
|0,0,1,0,0|
|0,0,0,1,0|
泛黃矩陣
Paste_Image.png
|1,0,0,0,100|
|0,1,0,0,100|
|0,0,1,0,0|
|0,0,0,1,0|
偏紅矩陣
Paste_Image.png
|2,0,0,0,0|
|0,1,0,0,0|
|0,0,1,0,0|
|0,0,0,1,0|
底片矩陣
Paste_Image.png
|-1,0,0,0,255|
|0,-1,0,0,255|
|0,0,-1,0,255|
|0,0,0,1,0|
主要代碼
開發流程簡介
1.獲取圖片資源draweBitmap
2.canvasBitmap獲取draweBitmap用于創建畫布canvas的大小
3.ColorMatrix設置顏色矩陣,ColorMatrixColorFilter加載ColorMatrix,paint設置ColorMatrixColorFilter
4.canvas使用paint繪制draweBitmap
5.imageView加載canvasBitmap
主視圖部分
public class ColorFilterView extends LinearLayout{
ImageView imageView;
Button btnSetting;
Bitmap draweBitmap;
Bitmap canvasBitmap;
Canvas canvas;
Paint paint;
float[] ColorMatrixFloat = new float[20];
ColorMatrixDialog colorMatrixDialog;
public ColorFilterView(Context context) {
super(context);
initView(context);
}
public ColorFilterView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context);
}
private void initView(final Context context) {
this.setOrientation(VERTICAL);
imageView = new ImageView(context);
BitmapFactory.Options option = new BitmapFactory.Options();
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity)context).getWindow().getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
draweBitmap = Utils.CompressImage(context, R.drawable.meizi,option,displayMetrics);
canvasBitmap = Bitmap.createBitmap(option.outWidth,option.outHeight, Bitmap.Config.ARGB_8888);
addView(imageView);
canvas = new Canvas(canvasBitmap);
paint = new Paint();
canvas.drawBitmap(draweBitmap,0,0,paint);
imageView.setImageBitmap(canvasBitmap);
btnSetting = new Button(context);
btnSetting.setText("MatrixSeeting");
btnSetting.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
colorMatrixDialog = new ColorMatrixDialog(context,ColorMatrixFloat);
colorMatrixDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
changeMatrix(ColorMatrixFloat);
}
});
colorMatrixDialog.show();
}
});
addView(btnSetting);
}
private void changeMatrix(float[] color){
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.set(color);
ColorMatrixColorFilter colorMatrixColorFilter = new ColorMatrixColorFilter(colorMatrix);
paint.setColorFilter(colorMatrixColorFilter);
canvas.drawBitmap(draweBitmap,0,0,paint);
imageView.setImageBitmap(canvasBitmap);
}
}
設置顏色矩陣Dialog
public class ColorMatrixDialog extends Dialog {
RecyclerView recyclerView;
List editTextList = new ArrayList<>();
float[] colors;
Button btnOk;
public ColorMatrixDialog(Context context,float[] colors) {
super(context);
init(context);
this.colors = colors;
}
public ColorMatrixDialog(Context context, int themeResId) {
super(context, themeResId);
init(context);
}
private void init(Context context){
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
recyclerView = new RecyclerView(context);
recyclerView.setLayoutManager(new GridLayoutManager(context,5));
recyclerView.setAdapter(new EditextAdapter());
linearLayout.addView(recyclerView);
btnOk = new Button(context);
btnOk.setText("OK");
btnOk.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int num = 0;
for(EditText editText : editTextList){
try {
String value = editText.getText().toString();
float floatValue = Float.valueOf(value);
colors[num] = floatValue;
}catch (NumberFormatException e){
e.printStackTrace();
}
num++;
}
dismiss();
}
});
linearLayout.addView(btnOk);
addContentView(linearLayout,new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
class EditextAdapter extends RecyclerView.Adapter{
@Override
public EditTextViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
EditText editText = new EditText(parent.getContext());
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.weight = 1;
editText.setLayoutParams(layoutParams);
editText.setGravity(View.TEXT_ALIGNMENT_CENTER);
editText.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_FLAG_DECIMAL|InputType.TYPE_NUMBER_FLAG_SIGNED);
editTextList.add(editText);
return new EditTextViewHolder(editText);
}
@Override
public void onBindViewHolder(EditTextViewHolder holder, int position) {
holder.editText.setText("0");
}
@Override
public int getItemCount() {
return 20;
}
}
class EditTextViewHolder extends RecyclerView.ViewHolder{
EditText editText;
public EditTextViewHolder(View itemView) {
super(itemView);
editText = (EditText)itemView;
}
}
}
補充內容
除了使用顏色矩陣改變,在官方文檔中還可以看到ColorMatrix另外幾個方法
Paste_Image.png
Paste_Image.png
Paste_Image.png
這三個方法分別設置飽和度、亮度、色相。
演示代碼
private void changeRGBA(){
float R = (rSeekBar.getProgress() -127) * 1.0f /127 * 180;
float G = gSeekBar.getProgress() * 1.0f / 127;
float B = bSeekBar.getProgress() * 1.0f / 127;
//色相
ColorMatrix colorMatrixRotate = new ColorMatrix();
colorMatrixRotate.setRotate(0,R);
colorMatrixRotate.setRotate(1,R);
colorMatrixRotate.setRotate(2,R);
//飽和度
ColorMatrix colorMatrixSaturation = new ColorMatrix();
colorMatrixSaturation.setSaturation(G);
//亮度
ColorMatrix colorMatrixScale = new ColorMatrix();
colorMatrixScale.setScale(B,B,B,1);
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.postConcat(colorMatrixRotate);
colorMatrix.postConcat(colorMatrixSaturation);
colorMatrix.postConcat(colorMatrixScale);
ColorMatrixColorFilter colorMatrixColorFilter = new ColorMatrixColorFilter(colorMatrix);
paint.setColorFilter(colorMatrixColorFilter);
canvas.drawBitmap(draweBitmap,0,0,paint);
imageView.setImageBitmap(canvasBitmap);
}
效果展示
620019632-5815ffd94819e_articlex.gif
總結
以上是生活随笔為你收集整理的android自定义滤镜,【Android】自定义View那点事(三)ColorFilter篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 名人堂内存灯:三招教你如何轻松关闭
- 下一篇: chrome 70 android,An