需要图片和源码点赞关注收藏后评论区留言~~~
一、位图与图形互转
Drawable用于在界面上展示图片,Bitmap用于加工图像数据,所以两者之间的转换非常有必要,位图图形BitmapDrawable正是二者之间的桥梁,图形对象与位图对象互相转换都需要它。
图形对象转换成位图对象有个前提,就是该图形原本便是位图格式,否则会转换失败
Drawable类有个setAlpha方法,可以设置图形的灰度值,下面是位图转换成图形对象后再调用setAlpha方法 效果如下
可见不同的灰度比例会有不同的效果
代码如下
Java类
package com.example.picture; import androidx.appcompat.app.AppCompatActivity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.Spinner; public class DrawableConvertActivity extends AppCompatActivity { private Bitmap mOriginBitmap; // 原始位图 private ImageView iv_picture; // 声明一个图像视图对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drawable_convert); iv_picture = findViewById(R.id.iv_picture); mOriginBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mandarin_duck); initAlphaSpinner(); // 初始化灰度比例下拉框 } // 初始化灰度比例下拉框 private void initAlphaSpinner() { ArrayAdapter<String> alphaAdapter = new ArrayAdapter<>(this, R.layout.item_select, alphaNameArray); Spinner sp_alpha = findViewById(R.id.sp_alpha); sp_alpha.setPrompt("请选择灰度比例"); sp_alpha.setAdapter(alphaAdapter); sp_alpha.setOnItemSelectedListener(new AlphaSelectedListener()); sp_alpha.setSelection(0); } private String[] alphaNameArray = {"1", "0.75", "0.5", "0.25", "0"}; class AlphaSelectedListener implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { double ratio = Double.parseDouble(alphaNameArray[arg2]); // 根据指定位图创建图形对象 Drawable drawable = new BitmapDrawable(getResources(), mOriginBitmap); drawable.setAlpha((int) (255*ratio)); // 设置图形的灰度值 iv_picture.setImageDrawable(drawable); // 设置图像视图的图形对象 } public void onNothingSelected(AdapterView<?> arg0) {} } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="40dp"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingLeft="5dp" android:gravity="center" android:text="请选择灰度比例" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_alpha" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:spinnerMode="dialog" /> </LinearLayout> <ImageView android:id="@+id/iv_picture" android:layout_width="match_parent" android:layout_height="200dp" android:scaleType="centerInside" /> </LinearLayout>
二、剪裁图形内部区域
有时候为了美观,并不会显示整个图像,而是显示剪裁后的图像,比如QQ的圆形头像等等。圆形剪裁正是位图图形的拿手好戏,只要调用画笔工具的setShader方法,设置位图着色器即可
下面实现 椭圆 圆角矩形 圆形的剪裁效果
代码如下
Java类
package com.example.picture; import androidx.appcompat.app.AppCompatActivity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.Spinner; import com.example.picture.widget.CircleDrawable; import com.example.picture.widget.OvalDrawable; import com.example.picture.widget.RoundDrawable; public class DrawableCutActivity extends AppCompatActivity { private Bitmap mOriginBitmap; // 原始位图 private ImageView iv_picture; // 声明一个图像视图对象 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drawable_cut); iv_picture = findViewById(R.id.iv_picture); mOriginBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mandarin_duck); initMethodSpinner(); // 初始化剪裁方式下拉框 } // 初始化剪裁方式下拉框 private void initMethodSpinner() { ArrayAdapter<String> methodAdapter = new ArrayAdapter<>(this, R.layout.item_select, methodArray); Spinner sp_method = findViewById(R.id.sp_method); sp_method.setPrompt("请选择剪裁方式"); sp_method.setAdapter(methodAdapter); sp_method.setOnItemSelectedListener(new MethodSelectedListener()); sp_method.setSelection(0); } private String[] methodArray = {"不裁剪", "圆形剪裁", "椭圆剪裁", "圆角矩形剪裁"}; class MethodSelectedListener implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { if (arg2 == 0) { // 不裁剪 iv_picture.setImageBitmap(mOriginBitmap); // 设置图像视图的位图对象 } else if (arg2 == 1) { // 圆形剪裁 Drawable drawable = new CircleDrawable(DrawableCutActivity.this, mOriginBitmap); iv_picture.setImageDrawable(drawable); // 设置图像视图的图形对象 } else if (arg2 == 2) { // 椭圆剪裁 Drawable drawable = new OvalDrawable(DrawableCutActivity.this, mOriginBitmap); iv_picture.setImageDrawable(drawable); // 设置图像视图的图形对象 } else if (arg2 == 3) { // 圆角矩形剪裁 Drawable drawable = new RoundDrawable(DrawableCutActivity.this, mOriginBitmap); iv_picture.setImageDrawable(drawable); // 设置图像视图的图形对象 } } public void onNothingSelected(AdapterView<?> arg0) {} } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="40dp"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingLeft="5dp" android:gravity="center" android:text="请选择剪裁方式" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_method" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:spinnerMode="dialog" /> </LinearLayout> <ImageView android:id="@+id/iv_picture" android:layout_width="match_parent" android:layout_height="200dp" android:scaleType="centerInside" /> </LinearLayout>
三、给图形添加小部件
除了剪裁图形之外,还能给图形添加小部件,比如文字,图标等等,原来自定义图形类的时候,重写draw方法等同于重写视图的onDraw方法,因此在draw方法中就可以添加图案。
此处可以设置个性化字体,用到了字体工具Typeface的createFromAsset方法,该方法允许从assets目录下的字体文件生成字体对象,然后调用画笔对象的setTypeface方法,就能使文字呈现对应的字体样式
同样能给图片加水印 效果如下
代码如下
Java类
package com.example.picture; import androidx.appcompat.app.AppCompatActivity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ImageView; import android.widget.Spinner; import com.example.picture.widget.MarkTextDrawable; public class DrawableTextActivity extends AppCompatActivity { private final static String TAG = "DrawableTextActivity"; private Bitmap mOriginBitmap; // 原始位图 private ImageView iv_picture; // 声明一个图像视图对象 private Typeface[] mTypeFaceArray; // 字体数组 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_drawable_text); iv_picture = findViewById(R.id.iv_picture); mOriginBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.mandarin_duck); iv_picture.setImageBitmap(mOriginBitmap); // 设置图像视图的位图对象 new Handler(Looper.myLooper()).post(() -> loadTypeFace()); // 加载字体文件 } // 加载字体文件 private void loadTypeFace() { mTypeFaceArray = new Typeface[fontFileArray.length]; for (int i=0; i<fontFileArray.length; i++) { String fontFile = "fonts/" + fontFileArray[i] + ".ttf"; // 根据assets目录下的字体文件创建字体对象 mTypeFaceArray[i] = Typeface.createFromAsset(getAssets(), fontFile); } initFontSpinner(); // 初始化中文字体下拉框 } // 初始化中文字体下拉框 private void initFontSpinner() { ArrayAdapter<String> fontAdapter = new ArrayAdapter<>(this, R.layout.item_select, fontNameArray); Spinner sp_font = findViewById(R.id.sp_font); sp_font.setPrompt("请选择中文字体"); sp_font.setAdapter(fontAdapter); sp_font.setOnItemSelectedListener(new FontSelectedListener()); sp_font.setSelection(0); } private String[] fontNameArray = {"常规", "仿宋", "楷体", "隶书", "黑体", "幼圆", "华文行楷", "华文新魏", "华文彩云", "华文琥珀", "方正舒体", "方正姚体"}; private String[] fontFileArray = {"Regular", "FangSong", "KaiTi", "LiShu", "HeiTi", "YouYuan", "HangKai", "XinWei", "CaiYun", "HuPo", "ShuTi", "YaoTi"}; class FontSelectedListener implements AdapterView.OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // 根据指定位图创建水印图形对象 MarkTextDrawable drawable = new MarkTextDrawable(DrawableTextActivity.this, mOriginBitmap); drawable.setMarkerText("鸳鸯戏水", mTypeFaceArray[arg2]); // 设置水印文字及其字体 iv_picture.setImageDrawable(drawable); // 设置图像视图的图形对象 } public void onNothingSelected(AdapterView<?> arg0) {} } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp"> <TextView android:layout_width="wrap_content" android:layout_height="match_parent" android:paddingLeft="5dp" android:gravity="center" android:text="请选择中文字体" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_font" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" android:spinnerMode="dialog" /> </LinearLayout> <ImageView android:id="@+id/iv_picture" android:layout_width="match_parent" android:layout_height="200dp" android:scaleType="centerInside" /> </LinearLayout>
创作不易 觉得有帮助请 点赞关注收藏~~~