
原文链接: >
需要用到类似QQ头像选择的一个功能,让用户从手机或者自己拍照并图图像大小剪裁之后选择,当时觉得很实用,但是自己不知道怎么实现。
最近参考同事写的代码并自己在网上查阅了相关信息,发现大概都是同样的方式,自己简单整合了一下,可以实现基本的功能,至于上传方面还没有深入研究。
裁剪
package comxiaomapiccutdemo;
import javaioFile;
import androidappActivity;
import androidappAlertDialog;
import androidcontentDialogInterface;
import androidcontentIntent;
import androidgraphicsBitmap;
import androidgraphicsdrawableBitmapDrawable;
import androidgraphicsdrawableDrawable;
import androidnetUri;
import androidosBundle;
import androidosEnvironment;
import androidproviderMediaStore;
import androidviewView;
import androidviewViewOnClickListener;
import androidwidgetButton;
import androidwidgetImageButton;
import androidwidgetImageView;
/
@Title: PicCutDemoActivityjava
@Package comxiaomapiccutdemo
@Description: 裁剪功能测试
@author XiaoMa
/
public class PicCutDemoActivity extends Activity implements OnClickListener {
private ImageButton ib = null;
private ImageView iv = null;
private Button btn = null;
private String tp = null;
/ Called when the activity is first created /
@Override
public void onCreate(Bundle savedInstanceState) {
superonCreate(savedInstanceState);
setContentView(Rlayoutmain);
//初始化
init();
}
/
初始化方法实现
/
private void init() {
ib = (ImageButton) findViewById(RidimageButton1);
iv = (ImageView) findViewById(RidimageView1);
btn = (Button) findViewById(Ridbutton1);
ibsetOnClickListener(this);
ivsetOnClickListener(this);
btnsetOnClickListener(this);
}
/
控件点击事件实现
因为有朋友问不同控件的背景图裁剪怎么实现,
我就在这个地方用了三个控件,只为了自己记录学习
大家觉得没用的可以跳过啦
/
@Override
public void onClick(View v) {
switch (vgetId()) {
case RidimageButton1:
ShowPickDialog();
break;
case RidimageView1:
ShowPickDialog();
break;
case Ridbutton1:
ShowPickDialog();
break;
default:
break;
}
}
/
选择提示对话框
/
private void ShowPickDialog() {
new AlertDialogBuilder(this)
setTitle("设置头像")
setNegativeButton("相册", new DialogInterfaceOnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialogdismiss();
/
刚开始,我自己也不知道ACTION_PICK是干嘛的,后来直接看Intent源码,
可以发现里面很多东西,Intent是个很强大的东西,大家一定仔细阅读下
/
Intent intent = new Intent(IntentACTION_PICK, null);
/
下面这句话,与其它方式写是一样的效果,如果:
intentsetData(MediaStoreImagesMediaEXTERNAL_CONTENT_URI);
intentsetType(""image/");设置数据类型
如果朋友们要限制上传到服务器的类型时可以直接写如:"image/jpeg 、 image/png等的类型"
这个地方小马有个疑问,希望高手解答下:就是这个数据URI与类型为什么要分两种形式来写呀?有什么区别?
/
intentsetDataAndType(
MediaStoreImagesMediaEXTERNAL_CONTENT_URI,
"image/");
startActivityForResult(intent, 1);
}
})
setPositiveButton("拍照", new DialogInterfaceOnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialogdismiss();
/
下面这句还是老样子,调用快速拍照功能,至于为什么叫快速拍照,大家可以参考如下官方
文档,you_sdk_path/docs/guide/topics/media/camerahtml
我刚看的时候因为太长就认真看,其实是错的,这个里面有用的太多了,所以大家不要认为
官方文档太长了就不看了,其实是错的,这个地方小马也错了,必须改正
/
Intent intent = new Intent(
MediaStoreACTION_IMAGE_CAPTURE);
//下面这句指定调用相机拍照后的照片存储的路径
intentputExtra(MediaStoreEXTRA_OUTPUT, Uri
fromFile(new File(Environment
getExternalStorageDirectory(),
"xiaomajpg")));
startActivityForResult(intent, 2);
}
})show();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// 如果是直接从相册获取
case 1:
startPhotoZoom(datagetData());
break;
// 如果是调用相机拍照时
case 2:
File temp = new File(EnvironmentgetExternalStorageDirectory()
+ "/xiaomajpg");
startPhotoZoom(UrifromFile(temp));
break;
// 取得裁剪后的
case 3:
/
非空判断大家一定要验证,如果不验证的话,
在剪裁之后如果发现不满意,要重新裁剪,丢弃
当前功能时,会报NullException,小马只
在这个地方加下,大家可以根据不同情况在合适的
地方做判断处理类似情况
/
if(data != null){
setPicToView(data);
}
break;
default:
break;
}
superonActivityResult(requestCode, resultCode, data);
}
/
裁剪方法实现
@param uri
/
public void startPhotoZoom(Uri uri) {
/
至于下面这个Intent的ACTION是怎么知道的,大家可以看下自己路径下的如下网页
yourself_sdk_path/docs/reference/android/content/Intenthtml
直接在里面Ctrl+F搜:CROP ,之前小马没仔细看过,其实安卓系统早已经有自带裁剪功能,
是直接调本地库的,小马不懂C C++ 这个不做详细了解去了,有轮子就用轮子,不再研究轮子是怎么
制做的了吼吼
/
Intent intent = new Intent("comandroidcameraactionCROP");
intentsetDataAndType(uri, "image/");
//下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
intentputExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intentputExtra("aspectX", 1);
intentputExtra("aspectY", 1);
// outputX outputY 是裁剪宽高
intentputExtra("outputX", 150);
intentputExtra("outputY", 150);
intentputExtra("return-data", true);
startActivityForResult(intent, 3);
}
/
保存裁剪之后的数据
@param picdata
/
private void setPicToView(Intent picdata) {
Bundle extras = picdatagetExtras();
if (extras != null) {
Bitmap photo = extrasgetParcelable("data");
Drawable drawable = new BitmapDrawable(photo);
/
下面注释的方法是将裁剪之后的以Base64Coder的字符方式上
传到服务器,QQ头像上传采用的方法跟这个类似
/
/ByteArrayOutputStream stream = new ByteArrayOutputStream();
photocompress(BitmapCompressFormatJPEG, 60, stream);
byte[] b = streamtoByteArray();
// 将流以字符串形式存储下来
tp = new String(Base64CoderencodeLines(b));
这个地方大家可以写下给服务器上传的实现,直接把tp直接上传就可以了,
服务器处理的方法是服务器那边的事了,吼吼
如果下载到的服务器的数据还是以Base64Coder的形式的话,可以用以下方式转换
为我们可以用的类型就OK啦吼吼
Bitmap dBitmap = BitmapFactorydecodeFile(tp);
Drawable drawable = new BitmapDrawable(dBitmap);
/
ibsetBackgroundDrawable(drawable);
ivsetBackgroundDrawable(drawable);
}
}
}
1遍历sdcard文件夹(指定层次深度 searchDeep ),如果文件夹发现 , 添加到已搜索到的文件列表中,并跳入下一个文件夹搜索
2使用 ContentResolver 搜索 添加搜索标签(png,jpg,jpeg,gif 等) 优点:更快速
压缩调用
第一步-->
采样率压缩:设置 BitmapFactoryOptionsinSampleSize 大小
第二步-->
PNG:尺寸压缩( Config:ARGB_4444 ,工具: Canvas );
JPG:尺寸压缩( Config:ARGB_565 ,工具: Canvas )+压缩质量( bitmapcompress() )
注 :
1GIF不做压缩处理
2尺寸压缩:改变宽高(png,jpg)
3压缩质量:改变文件大小(适用jpg,png无效)
以上就是关于(译)uCrop介绍 —— 我们自己的Android图片裁剪库全部的内容,包括:(译)uCrop介绍 —— 我们自己的Android图片裁剪库、Android 11 调用系统图片裁剪后,图片保存不了的解决方案、android 开发中获取sd卡或照相机的照片怎样裁剪呈圆形等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)