37_Crop 选择相册图片并手动裁切

 
ss
 
一、 功能:
获取相册图片并手动进行裁切
 
二、简介
基于ASOP (Android Open-Source Project:Android 开放源代码项目)
维护更新频次不是很高
 
三、主要特点
Gradle构建和AAR
现代化的UI
向后兼容到SDK 10
配置简单
 
四、使用
依赖这个 AAR 发布在 Maven Central :
1
compile 'com.soundcloud.android:android-crop:1.0.1@aar'
在你的 manifest 文件中申明 CropImageActivity :
1
<activity android : name = "com.soundcloud.android.crop.CropImageActivity" />
选择
这个库提供了一个实用的方法期待一个图像选择器:
1
Crop . pickImage ( activity )
裁切
1
Crop . of ( inputUri , outputUri ). asSquare (). start ( activity )
监听裁切的结果:
1
2
3
4
5
6
@Override
protected void onActivityResult ( int requestCode , int resultCode , Intent result ) {
     if ( requestCode == Crop . REQUEST_CROP && resultCode == RESULT_OK ) {
         doSomethingWithCroppedImage ( outputUri );
     }
}
裁切见面的属性是可以定制的,详情请查看实例项目的 主题
使用者
使用该库的应用程序包括: SoundCloud Depop Polyvore , TextSecure
 
五 Demo:
1、 gradle,在dependencies节点下添加:
compile 'com.soundcloud.android.crop:lib_crop:1.0.0'
2、 在清单文件中注册裁剪功能所在的页面:
< activity android:name = "com.soundcloud.android.crop.CropImageActivity" />
3、 代码:
public class MainActivity extends AppCompatActivity{

private	ImageViewiv;

@Override
protected voidonCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
	iv=(ImageView)findViewById(R.id.iv);
}

//1、进入相册
public voidpick(View v){
   Crop.pickImage(this);
}

@Override
protected voidonActivityResult(intrequestCode,intresultCode,Intent data){
   super.onActivityResult(requestCode,resultCode,data);
   if(requestCode==Crop.REQUEST_PICK&&resultCode==RESULT_OK){
		//2、从相册回来,进入裁剪页
        beginCrop(data.getData());
    }else if(requestCode==Crop.REQUEST_CROP){
		//3、从裁剪页回来,设置图片
        handleCrop(resultCode,data);
    }
}

private voidhandleCrop(intresultCode,Intent result){
    if(resultCode==RESULT_OK){
        Uri uri=Crop.getOutput(result);
        inth=getResources().getDimensionPixelSize(R.dimen.height);
        Bitmap bitmap=UtilsBitmap.decodeUri(this,uri,h,h);
        iv.setImageBitmap(bitmap);
    }else if(resultCode==Crop.RESULT_ERROR){
        Toast.makeText(this,Crop.getError(result).getMessage(),Toast.LENGTH_SHORT).show();
    }
}

private voidbeginCrop(Uri source){
   Uri destination=Uri.fromFile(new File(getCacheDir(),"cropped_"+System.currentTimeMillis()+".jpg"));
   Crop.of(source,destination).asSquare().start(this);
}
}

Utils:
public classUtilsBitmap{
/**
 * 读取一个缩放后的图片,限定图片大小,避免OOM
 * @paramuri图片uri,支持“file://”、“content://”
 * @parammaxWidth最大允许宽度
 * @parammaxHeight最大允许高度
 * @return返回一个缩放后的Bitmap,失败则返回null
 */
public staticBitmapdecodeUri(Context context,Uri uri,intmaxWidth,intmaxHeight){
    BitmapFactory.Options options=newBitmapFactory.Options();
    options.inJustDecodeBounds=true; //只读取图片尺寸
    resolveUri(context,uri,options);

	//计算实际缩放比例
    intscale=1;
    for(inti=0;i<Integer.MAX_VALUE;i++){
		if((options.outWidth/scale>maxWidth&&options.outWidth/scale>maxWidth*1.4)||
			(options.outHeight/scale>maxHeight&&options.outHeight/scale>maxHeight*1.4)){
				scale++;
		}else{
			break;
		}
    }

    options.inSampleSize=scale;
    options.inJustDecodeBounds=false;//读取图片内容
    options.inPreferredConfig=Bitmap.Config.RGB_565;//根据情况进行修改
    Bitmap bitmap=null;
    try{
        bitmap=resolveUriForBitmap(context,uri,options);
    }catch(Throwable e){
        e.printStackTrace();
    }
    returnbitmap;
}


private static voidresolveUri(Context context,Uri uri,BitmapFactory.Options options){
    if(uri==null){
        return;
    }
    String scheme=uri.getScheme();
    if(ContentResolver.SCHEME_CONTENT.equals(scheme)||
        ContentResolver.SCHEME_FILE.equals(scheme)){
			InputStream stream=null;
        try{
			stream=context.getContentResolver().openInputStream(uri);
			BitmapFactory.decodeStream(stream,null,options);
        }catch(Exception e){
			Log.w("resolveUri","Unable to open content: "+uri,e);
        }finally{
			if(stream!=null){
				try{
					stream.close();
				}catch(IOException e){
					Log.w("resolveUri","Unable to close content: "+uri,e);
				}
			}
        }
    }else if(ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)){
        Log.w("resolveUri","Unable to close content: "+uri);
    }else{
        Log.w("resolveUri","Unable to close content: "+uri);
    }
}

private staticBitmapresolveUriForBitmap(Context context,Uri uri,BitmapFactory.Options options){
    if(uri==null){
        return null;
    }

    Bitmap bitmap=null;
    String scheme=uri.getScheme();
    if(ContentResolver.SCHEME_CONTENT.equals(scheme)||
        ContentResolver.SCHEME_FILE.equals(scheme)){
        InputStream stream=null;
        try{
			stream=context.getContentResolver().openInputStream(uri);
			bitmap=BitmapFactory.decodeStream(stream,null,options);
        }catch(Exception e){
			Log.w("resolveUriForBitmap","Unable to open content: "+uri,e);
        }finally{
			if(stream!=null){
				try{
					stream.close();
				}catch(IOException e){
					Log.w("resolveUriForBitmap","Unable to close content: "+uri,e);
				}
			}
		}
	}else if(ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)){
        Log.w("resolveUriForBitmap","Unable to close content: "+uri);
    }else{
        Log.w("resolveUriForBitmap","Unable to close content: "+uri);
    }

    returnbitmap;
}
}




请详细解释下这段代码Rect<float> Framer::ComputeActiveCropRegion(int frame_number) { const float min_crop_size = 1.0f / options_.max_zoom_ratio; const float new_x_crop_size = std::clamp(region_of_interest_.width * options_.target_crop_to_roi_ratio, min_crop_size, 1.0f); const float new_y_crop_size = std::clamp(region_of_interest_.height * options_.target_crop_to_roi_ratio, min_crop_size, 1.0f); // We expand the raw crop region to match the desired output aspect ratio. const float target_aspect_ratio = static_cast<float>(options_.input_size.height) / static_cast<float>(options_.input_size.width) * static_cast<float>(options_.target_aspect_ratio_x) / static_cast<float>(options_.target_aspect_ratio_y); Rect<float> new_crop; if (new_x_crop_size <= new_y_crop_size * target_aspect_ratio) { new_crop.width = std::min(new_y_crop_size * target_aspect_ratio, 1.0f); new_crop.height = new_crop.width / target_aspect_ratio; } else { new_crop.height = std::min(new_x_crop_size / target_aspect_ratio, 1.0f); new_crop.width = new_crop.height * target_aspect_ratio; } const float roi_x_mid = region_of_interest_.left + (region_of_interest_.width / 2); const float roi_y_mid = region_of_interest_.top + (region_of_interest_.height / 2); new_crop.left = std::clamp(roi_x_mid - (new_crop.width / 2), 0.0f, 1.0f - new_crop.width); new_crop.top = std::clamp(roi_y_mid - (new_crop.height / 2), 0.0f, 1.0f - new_crop.height); const float normalized_crop_strength = std::powf(options_.crop_filter_strength, ElapsedTimeMs(timestamp_) / kUnitTimeSlice); active_crop_region_.left = IirFilter(active_crop_region_.left, new_crop.left, normalized_crop_strength); active_crop_region_.top = IirFilter(active_crop_region_.top, new_crop.top, normalized_crop_strength); active_crop_region_.width = IirFilter( active_crop_region_.width, new_crop.width, normalized_crop_strength); active_crop_region_.height = IirFilter( active_crop_region_.height, new_crop.height, normalized_crop_strength); timestamp_ = base::TimeTicks::Now(); if (VLOG_IS_ON(2)) { DVLOGFID(2, frame_number) << "region_of_interest=" << region_of_interest_; DVLOGFID(2, frame_number) << "new_crop_region=" << new_crop; DVLOGFID(2, frame_number) << "active_crop_region=" << active_crop_region_; } return active_crop_region_; }
06-09
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值