原圖:
處理後:
下面貼代碼:
一、圖片處理層:
package com.jacp.tone.view;</p><p>import java.util.ArrayList;</p><p>import android.content.Context;<br />import android.graphics.Bitmap;<br />import android.graphics.Canvas;<br />import android.graphics.ColorMatrix;<br />import android.graphics.ColorMatrixColorFilter;<br />import android.graphics.Paint;<br />import android.view.Gravity;<br />import android.view.View;<br />import android.widget.LinearLayout;<br />import android.widget.SeekBar;<br />import android.widget.SeekBar.OnSeekBarChangeListener;<br />import android.widget.TextView;</p><p>import com.jacp.tone.R;</p><p>/**<br /> * 圖片調色處理<br /> * @author maylian7700@126.com<br /> *<br /> */<br />public class ToneLayer {</p><p>/**<br /> * 飽和度標識<br /> */<br />public static final int FLAG_SATURATION = 0x0;</p><p>/**<br /> * 亮度標識<br /> */<br />public static final int FLAG_LUM = 0x1;</p><p>/**<br /> * 色相標識<br /> */<br />public static final int FLAG_HUE = 0x2;</p><p>/**<br /> * 飽和度<br /> */<br />private TextView mSaturation;<br />private SeekBar mSaturationBar;</p><p>/**<br /> * 色相<br /> */<br />private TextView mHue;<br />private SeekBar mHueBar;</p><p>/**<br /> * 亮度<br /> */<br />private TextView mLum;<br />private SeekBar mLumBar;</p><p>private float mDensity;<br />private static final int TEXT_WIDTH = 50;</p><p>private LinearLayout mParent;</p><p>private ColorMatrix mLightnessMatrix;<br />private ColorMatrix mSaturationMatrix;<br />private ColorMatrix mHueMatrix;<br />private ColorMatrix mAllMatrix;</p><p>/**<br /> * 亮度<br /> */<br />private float mLumValue = 1F;</p><p>/**<br /> * 飽和度<br /> */<br />private float mSaturationValue = 0F;</p><p>/**<br /> * 色相<br /> */<br />private float mHueValue = 0F;</p><p>/**<br /> * SeekBar的中間值<br /> */<br />private static final int MIDDLE_VALUE = 127;</p><p>/**<br /> * SeekBar的最大值<br /> */<br />private static final int MAX_VALUE = 255;</p><p>private ArrayList<SeekBar> mSeekBars = new ArrayList<SeekBar>();</p><p>public ToneLayer(Context context) {<br />init(context);<br />}</p><p>private void init(Context context) {<br />mDensity = context.getResources().getDisplayMetrics().density;</p><p>mSaturation = new TextView(context);<br />mSaturation.setText(R.string.saturation);<br />mHue = new TextView(context);<br />mHue.setText(R.string.contrast);<br />mLum = new TextView(context);<br />mLum.setText(R.string.lightness);</p><p>mSaturationBar = new SeekBar(context);<br />mHueBar = new SeekBar(context);<br />mLumBar = new SeekBar(context);</p><p>mSeekBars.add(mSaturationBar);<br />mSeekBars.add(mHueBar);<br />mSeekBars.add(mLumBar);</p><p>for (int i = 0, size = mSeekBars.size(); i < size; i++) {<br />SeekBar seekBar = mSeekBars.get(i);<br />seekBar.setMax(MAX_VALUE);<br />seekBar.setProgress(MIDDLE_VALUE);<br />seekBar.setTag(i);<br />}</p><p>LinearLayout saturation = new LinearLayout(context);<br />saturation.setOrientation(LinearLayout.HORIZONTAL);<br />saturation.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));</p><p>LinearLayout.LayoutParams txtLayoutparams = new LinearLayout.LayoutParams((int) (TEXT_WIDTH * mDensity), LinearLayout.LayoutParams.MATCH_PARENT);<br />mSaturation.setGravity(Gravity.CENTER);<br />saturation.addView(mSaturation, txtLayoutparams);</p><p>LinearLayout.LayoutParams seekLayoutparams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);<br />saturation.addView(mSaturationBar, seekLayoutparams);</p><p>LinearLayout hue = new LinearLayout(context);<br />hue.setOrientation(LinearLayout.HORIZONTAL);<br />hue.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));</p><p>mHue.setGravity(Gravity.CENTER);<br />hue.addView(mHue, txtLayoutparams);<br />hue.addView(mHueBar, seekLayoutparams);</p><p>LinearLayout lum = new LinearLayout(context);<br />lum.setOrientation(LinearLayout.HORIZONTAL);<br />lum.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));</p><p>mLum.setGravity(Gravity.CENTER);<br />lum.addView(mLum, txtLayoutparams);<br />lum.addView(mLumBar, seekLayoutparams);</p><p>mParent = new LinearLayout(context);<br />mParent.setOrientation(LinearLayout.VERTICAL);<br />mParent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));<br />mParent.addView(saturation);<br />mParent.addView(hue);<br />mParent.addView(lum);<br />}</p><p>public View getParentView() {<br />return mParent;<br />}</p><p>/**<br /> * 設定飽和度值<br /> * @param saturation<br /> */<br />public void setSaturation(int saturation) {<br />mSaturationValue = saturation * 1.0F / MIDDLE_VALUE;<br />}</p><p>/**<br /> * 設定色相值<br /> * @param hue<br /> */<br />public void setHue(int hue) {<br />mHueValue = hue * 1.0F / MIDDLE_VALUE;<br />}</p><p>/**<br /> * 設定亮度值<br /> * @param lum<br /> */<br />public void setLum(int lum) {<br />mLumValue = (lum - MIDDLE_VALUE) * 1.0F / MIDDLE_VALUE * 180;<br />}</p><p>public ArrayList<SeekBar> getSeekBars()<br />{<br />return mSeekBars;<br />}</p><p>/**<br /> *<br /> * @param flag<br /> * 位元位0 表示是否改變色相,比位1表示是否改變飽和度,位元位2表示是否改變明亮度<br /> */<br />public Bitmap handleImage(Bitmap bm, int flag) {<br />Bitmap bmp = Bitmap.createBitmap(bm.getWidth(), bm.getHeight(),<br />Bitmap.Config.ARGB_8888);<br />// 建立一個相同尺寸的可變的位元影像區,用於繪製調色後的圖片<br />Canvas canvas = new Canvas(bmp); // 得到畫筆對象<br />Paint paint = new Paint(); // 建立paint<br />paint.setAntiAlias(true); // 設定消除鋸齒,也即是邊緣做平滑處理<br />if (null == mAllMatrix) {<br />mAllMatrix = new ColorMatrix();<br />}</p><p>if (null == mLightnessMatrix) {<br />mLightnessMatrix = new ColorMatrix(); // 用於顏色變換的矩陣,android位元影像顏色變化處理主要是靠該對象完成<br />}</p><p>if (null == mSaturationMatrix) {<br />mSaturationMatrix = new ColorMatrix();<br />}</p><p>if (null == mHueMatrix) {<br />mHueMatrix = new ColorMatrix();<br />}</p><p>switch (flag) {<br />case FLAG_HUE: // 需要改變色相<br />mHueMatrix.reset();<br />mHueMatrix.setScale(mHueValue, mHueValue, mHueValue, 1); // 紅、綠、藍三分量按相同的比例,最後一個參數1表示透明度不做變化,此函數詳細說明參考<br />// // android<br />// doc<br />break;<br />case FLAG_SATURATION: // 需要改變飽和度<br />// saturation 飽和度值,最小可設為0,此時對應的是灰階圖(也就是俗話的“黑白圖”),<br />// 為1表示飽和度不變,設定大於1,就顯示過飽和<br />mSaturationMatrix.reset();<br />mSaturationMatrix.setSaturation(mSaturationValue);<br />break;<br />case FLAG_LUM: // 亮度<br />// hueColor就是色輪旋轉的角度,正值表示順時針旋轉,負值表示逆時針旋轉<br />mLightnessMatrix.reset(); // 設為預設值<br />mLightnessMatrix.setRotate(0, mLumValue); // 控制讓紅色區在色輪上旋轉的角度<br />mLightnessMatrix.setRotate(1, mLumValue); // 控制讓綠紅色區在色輪上旋轉的角度<br />mLightnessMatrix.setRotate(2, mLumValue); // 控制讓藍色區在色輪上旋轉的角度<br />// 這裡相當於改變的是全圖的色相<br />break;<br />}<br />mAllMatrix.reset();<br />mAllMatrix.postConcat(mHueMatrix);<br />mAllMatrix.postConcat(mSaturationMatrix); // 效果疊加<br />mAllMatrix.postConcat(mLightnessMatrix); // 效果疊加</p><p>paint.setColorFilter(new ColorMatrixColorFilter(mAllMatrix));// 設定顏色變換效果<br />canvas.drawBitmap(bm, 0, 0, paint); // 將顏色變化後的圖片輸出到新建立的位元影像區<br />// 返回新的位元影像,也即調色處理後的圖片<br />return bmp;<br />}</p><p>}<br />
二、主介面:
package com.jacp.tone;</p><p>import java.util.ArrayList;</p><p>import android.app.Activity;<br />import android.graphics.Bitmap;<br />import android.graphics.BitmapFactory;<br />import android.os.Bundle;<br />import android.widget.ImageView;<br />import android.widget.LinearLayout;<br />import android.widget.SeekBar;<br />import android.widget.SeekBar.OnSeekBarChangeListener;</p><p>import com.jacp.tone.view.ToneLayer;</p><p>/**<br /> * 啟動的主介面<br /> * @author maylian7700@126.com<br /> *<br /> */<br />public class ImageToneActivity extends Activity implements OnSeekBarChangeListener {<br />private ToneLayer mToneLayer;<br />private ImageView mImageView;<br />private Bitmap mBitmap;</p><p> @Override<br /> public void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main);</p><p> init();<br /> }</p><p> private void init()<br /> {<br /> mToneLayer = new ToneLayer(this);</p><p> mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);<br /> mImageView = (ImageView) findViewById(R.id.img_view);<br /> mImageView.setImageBitmap(mBitmap);<br /> ((LinearLayout) findViewById(R.id.tone_view)).addView(mToneLayer.getParentView());</p><p> ArrayList<SeekBar> seekBars = mToneLayer.getSeekBars();<br /> for (int i = 0, size = seekBars.size(); i < size; i++)<br /> {<br /> seekBars.get(i).setOnSeekBarChangeListener(this);<br /> }<br /> }</p><p>@Override<br />public void onProgressChanged(SeekBar seekBar, int progress,<br />boolean fromUser) {<br />int flag = (Integer) seekBar.getTag();<br />switch (flag)<br />{<br />case ToneLayer.FLAG_SATURATION:<br />mToneLayer.setSaturation(progress);<br />break;<br />case ToneLayer.FLAG_LUM:<br />mToneLayer.setLum(progress);<br />break;<br />case ToneLayer.FLAG_HUE:<br />mToneLayer.setHue(progress);<br />break;<br />}</p><p>mImageView.setImageBitmap(mToneLayer.handleImage(mBitmap, flag));<br />}</p><p>@Override<br />public void onStartTrackingTouch(SeekBar seekBar) {</p><p>}</p><p>@Override<br />public void onStopTrackingTouch(SeekBar seekBar) {</p><p>}<br />}
三、布局檔案:
<?xml version="1.0" encoding="utf-8"?><br /><ScrollView xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> ></p><p><LinearLayout<br /> android:layout_width="match_parent"<br /> android:layout_height="match_parent"<br /> android:orientation="vertical" ></p><p> <ImageView<br /> android:layout_width="wrap_content"<br /> android:layout_height="wrap_content"<br /> android:layout_weight="1"<br /> android:id="@+id/img_view"<br /> android:layout_gravity="center"<br /> /><br /> <LinearLayout<br /> android:layout_width="match_parent"<br /> android:layout_height="wrap_content"<br /> android:id="@+id/tone_view"<br /> /><br /></LinearLayout><br /></ScrollView>