AndroidのBitmap Shaderを利用して、自分のフレームを持つ丸い顔写真を作ります。
8649 ワード
効果は以下の通りです
Bitmap Shaderの簡単な紹介
1.
2.
3.
私たちが使用するのは
具体的に紹介します
画像をカスタマイズするために、枠の幅と色を設定します。まず、res/valuesディレクトリの下で、atrs.xmlファイルを新規作成します。中に書く内容は以下の通りです。
次に、私たちが得た
もう一つ強調したいのは、ここの
以上の操作を経て、私たちはもう丸い顔写真を描きました。下に枠を描きます。実はとても簡単です。私はもう一つ定義しただけです。
以上はAndroidがBitmap Shaderを利用してフレームの丸い顔写真を持っているすべての内容を作っています。この文章は皆さんにAndroidを開発する時に役に立ちます。もし疑問があれば、メッセージを残して交流してください。
Bitmap Shaderの簡単な紹介
Shader
とは何ですか?Shader
の種類はどのような種類がありますか?また、どのように使用するかは本論文の範疇に属さないです。この点についてよく知らない方は、まずShader
の基本的な使い方を学んでみてください。BitmapShader
の主な役割は、Paintオブジェクトを通じて、キャンバスに指定されたBitmap
を充填することであり、一連の効果を実現し、次の3つのモードを選択することができる。1.
CLAMP
-引張り、ここで引張りますのはピクチャの最後の要素で、絶えず繰り返します。この効果は画像が小さいですが、描く面積が大きい場合は明らかです。2.
REPEAT
-繰り返し、横方向の縦方向の連続的な繰り返しは、前のパターンとは違って、このようなモードは画像では比較的小さいので、要求を満たすことができません。3.
MIRROR
−ロールオーバ、このようなモードはREPEAT
と同様であるが、ここでの繰り返しはロールオーバの繰り返しであり、折り紙の効果と同じである。私たちが使用するのは
CLAMP
モードです。画像の大きさを制御すれば、画像が引き伸ばされないからです。具体的に紹介します
画像をカスタマイズするために、枠の幅と色を設定します。まず、res/valuesディレクトリの下で、atrs.xmlファイルを新規作成します。中に書く内容は以下の通りです。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyCustomView">
<attr name="mborder_color" format="color"></attr>
<attr name="mborder_width" format="dimension"></attr>
<attr name="msrc" format="reference"></attr>
</declare-styleable>
</resources>
もちろん、ここでは他の特性も追加できます。私たちが使用したい特性を定義した上は、カスタムView
でこれらの属性を解析して利用します。解析プロセスは以下の通りです。
TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
mBorderColor = type.getColor(R.styleable.MyCustomView_mborder_color,0);
mDrawable = type.getDrawable(R.styleable.MyCustomView_msrc);
// Drawable Bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
mBitmap = bitmapDrawable.getBitmap();
mBorderWidth = type.getDimensionPixelSize(R.styleable.MyCustomView_mborder_width, 2);
注目すべきはmSrc
属性の解析であり、取得はDrawable
オブジェクトであるため、Bitmap
オブジェクトに変換する必要がある。次に、私たちが得た
Bitmap
オブジェクトを用いて、円形の顔写真の描画を行います。BitmapShader
およびPaint
の初期化は、以下の通りです。
mSrcBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth, mHeight, false);
mShader = new BitmapShader(mSrcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);
mRadius = (mWidth - mBorderWidth * 2 - 4) / 2;
mCircleX = (mWidth) / 2;
mCircleY = (mHeight) / 2;
mSrcurBitmapは、得られた画像を適切に縮小または拡大し、我々の図形に対する要求に適応するものであるが、ここのmWidth
およびmHeight
は何であろうか?実際には、私たちが定義ビューで layout_width
とlayout_height
に伝達した値ですが、ここでは彼らに対して処理を行いました。すなわち最小値を選択して動作します。このようにすれば、幅が大きいか、幅が大きいか、幅が大きいかによって画像が充足された領域に不満をもたらす現象を回避することができます。なお、カスタムビューは、wrap_content
を特殊処理する必要があり、そうでなければ、システムはこの属性のビューを表示しない。どのように処理するかについては、この例のソースコードを見てもいいです。簡単です。多くの人が見ればわかると思います。もう一つ強調したいのは、ここの
mRadius
、つまり描く円の半径です。なぜ枠の幅をマイナスして2に乗るのですか?私たちの円はビューによって指定された幅や高さで描かれていますが、もし私たちが描いた円が指定されたビューの内側の円だったら、枠はどこにありますか?それは必ずビューの外に描かれます。そうすると、完全な枠が見えなくなります。だから、このようにマイナスする意味は枠のために空間をあけることにあります。以上の操作を経て、私たちはもう丸い顔写真を描きました。下に枠を描きます。実はとても簡単です。私はもう一つ定義しただけです。
Paint
オブジェクトを使って円を描いただけです。ブラシの初期化操作は以下の通りです。
mBorderPaint = new Paint();
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
はい、以下はonDraw()
関数で描画できます。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mCircleX, mCircleY, mRadius, mPaint);
canvas.drawCircle(mCircleX, mCircleY, mRadius, mBorderPaint);
}
このようにして、全体の効果は実現しました。次はどうやって使うかを見てみます。
<com.example.hwaphon.patheffecttest.MyView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginRight="8dp"
app:mborder_color="@android:color/holo_green_light"
app:mborder_width="4dp"
app:msrc="@drawable/myview_test"/>
容器の中に必ずこのように付け加えます。
xmlns:app=http://schemas.android.com/apk/res-auto
具体的に実現するコアコード
package com.example.hwaphon.patheffecttest;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
/**
* Created by Hwaphon on 2016/5/12.
*/
public class MyView extends View {
private Bitmap mBitmap;
private Drawable mDrawable;
private Bitmap mSrcBitmap;
private BitmapShader mShader;
private Paint mPaint;
private int mWidth, mHeight;
private int mRadius;
private int mCircleX, mCircleY;
private int mBorderColor;
private Paint mBorderPaint;
private int mBorderWidth;
public MyView(Context context) {
this(context, null);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray type = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView);
mBorderColor = type.getColor(R.styleable.MyCustomView_mborder_color,0);
mDrawable = type.getDrawable(R.styleable.MyCustomView_msrc);
// Drawable Bitmap
BitmapDrawable bitmapDrawable = (BitmapDrawable) mDrawable;
mBitmap = bitmapDrawable.getBitmap();
mBorderWidth = type.getDimensionPixelSize(R.styleable.MyCustomView_mborder_width, 2);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = measureWidth(widthMeasureSpec);
mHeight = measureHeight(heightMeasureSpec);
int temp = mWidth > mHeight ? mHeight : mWidth;
mWidth = mHeight = temp;
initView();
setMeasuredDimension(mWidth, mHeight);
}
private int measureHeight(int heightMeasureSpec) {
int size = MeasureSpec.getSize(heightMeasureSpec);
int sizeMode = MeasureSpec.getMode(heightMeasureSpec);
int result = 0;
if (sizeMode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = 200;
if (sizeMode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return result;
}
private int measureWidth(int widthMeasureSpec) {
int size = MeasureSpec.getSize(widthMeasureSpec);
int sizeMode = MeasureSpec.getMode(widthMeasureSpec);
int result = 0;
if (sizeMode == MeasureSpec.EXACTLY) {
result = size;
} else {
result = 200;
if (sizeMode == MeasureSpec.AT_MOST) {
result = Math.min(result, size);
}
}
return result;
}
private void initView() {
mSrcBitmap = Bitmap.createScaledBitmap(mBitmap, mWidth, mHeight, false);
mShader = new BitmapShader(mSrcBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);
mRadius = (mWidth - mBorderWidth * 2) / 2;
mCircleX = (mWidth) / 2;
mCircleY = (mHeight) / 2;
mBorderPaint = new Paint();
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setStrokeWidth(mBorderWidth);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeJoin(Paint.Join.ROUND);
mBorderPaint.setStrokeCap(Paint.Cap.ROUND);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(mCircleX, mCircleY, mRadius, mPaint);
canvas.drawCircle(mCircleX, mCircleY, mRadius, mBorderPaint);
}
}
締め括りをつける以上はAndroidがBitmap Shaderを利用してフレームの丸い顔写真を持っているすべての内容を作っています。この文章は皆さんにAndroidを開発する時に役に立ちます。もし疑問があれば、メッセージを残して交流してください。