在项目的兼容适配上碰到了一个问题,就是之前写好的上传头像功能在华为nexus6p原生机上不能使用了。

经过一番研究发现是以下两个问题导致的:

1、url的路径产生了变化,导致获取bitmap的方法跟着要变。

在华为nexus6p上是:

Bitmap    photo = BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData()));

在小米4(同为6.0系统,但是小米的修改系统造成了一定影响)或者其他低于6.0版本手机上是:

Bitmap     photo = data.getParcelableExtra("data");

解决方式参考so:http://stackoverflow.com/questions/32564041/java-lang-nullpointerexception-attempt-to-invoke-virtual-method-java-lang-stri

最后判断版本进行不同的获取操作:

      Bitmap photo = null;try {if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M && data.getData() != null) {photo = BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData()));} else {// in android version lower than M your method must workphoto = data.getParcelableExtra("data");}} catch (FileNotFoundException e) {e.printStackTrace();}


2、因为华为nexus6p使用的是google相册,所以从相册选择的照片是不支持修改功能的(拍照的图片没影响,是先存到本地路径的还没放进google相册,所以可以先进行裁剪),最后采取的办法是将相册选取的图片先复制一份拍好的图片到本地,再进行裁剪,代码如下:

 private void uploadImage(Bitmap photo) {if (photo == null) {LogUtils.d("裁剪后的photo为空");return;}//存到本地FileOutputStream b = null;File file = new File(Config.LOCAL_PORTRAIT_CUT_PATH);if (!file.exists()) {file.mkdirs();// 创建文件夹} else {//删除文件夹下所有文件CommonUtils.deleteFile(file);}localTempImgFileName = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";String fileName = Config.LOCAL_PORTRAIT_CUT_PATH + localTempImgFileName;try {b = new FileOutputStream(fileName);photo.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件} catch (FileNotFoundException e) {e.printStackTrace();} finally {try {b.flush();b.close();} catch (IOException e) {e.printStackTrace();}}
}

最后是最后实现的拍照+裁剪(左)和相册选择+裁剪(右),最后上传并同步照片的效果图:

最后是改功能Aty完整代码:

EditUserInfoActivity.java:

/*** Created by jiangzn on 16/10/3.*/
public class EditUserInfoActivity extends BaseActivity implements View.OnClickListener {@Bind(R.id.view_curtain_edituserinfo)View view_curtain_edituserinfo;             //幕布@Bind(R.id.btn_editportrait_eidtuserinfo)Button btn_editportrait_eidtuserinfo;       //头像选择按钮@Bind(R.id.btn_editsex_eidtuserinfo)Button btn_editsex_eidtuserinfo;            //性别选择按钮@Bind(R.id.btn_editnickname_eidtuserinfo)Button btn_editnickname_eidtuserinfo;       //修改昵称@Bind(R.id.btn_editsign_eidtuserinfo)Button btn_editsign_eidtuserinfo;           //修改签名@Bind(R.id.btn_bindphonenumber_eidtuserinfo)Button btn_bindphonenumber_eidtuserinfo;    //绑定手机号@Bind(R.id.layout_choose_edituserinfo)LinearLayout layout_choose_edituserinfo;    //选择布局@Bind(R.id.tv_choosetv1_edituserinfo)TextView tv_choosetv1_edituserinfo;@Bind(R.id.tv_choosetv2_edituserinfo)TextView tv_choosetv2_edituserinfo;@Bind(R.id.btn_choosebtn1_edituserinfo)Button btn_choosebtn1_edituserinfo;@Bind(R.id.btn_choosebtn2_edituserinfo)Button btn_choosebtn2_edituserinfo;@Bind(R.id.btn_chooseclose_edituserinfo)Button btn_chooseclose_edituserinfo;@Bind(R.id.civ_userhead_edituserinfo)NGNormalCircleImageView civ_userhead_edituserinfo;@Bind(R.id.btn_back_edituserinfo)ImageButton btn_back_edituserinfo;@Bind(R.id.tv_username_edituserinfo)TextView tv_username_edituserinfo;@Bind(R.id.tv_usergender_edituserinfo)TextView tv_usergender_edituserinfo;@Bind(R.id.tv_sign_edituserinfo)TextView tv_sign_edituserinfo;private String localTempImgFileName = "";private Boolean isupdate = false;   //数据是否更新private static final int REQUEST_CAMERA = 1;private static final int REQUEST_READ_WIRTE = 2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Overrideprotected int getContentViewLayoutID() {return R.layout.activity_edituserinfo;}@Bind(R.id.targetview_edituserinfo)View targetview_edituserinfo;@Overrideprotected View getLoadingTargetView() {return null;}private void initData() {UserInfo tempUserInfo = UserInfoManager.getInstance(EditUserInfoActivity.this).getUserInfo();if (!CommonUtils.isNull(tempUserInfo)) {//头像Glide.with(EditUserInfoActivity.this).load(tempUserInfo.getHeadUrl()).into(civ_userhead_edituserinfo);//昵称tv_username_edituserinfo.setText(CommonUtils.notNull(tempUserInfo.getNickName()));//性别if (tempUserInfo.getGender() == null) {tv_usergender_edituserinfo.setText("未设置");} else if (tempUserInfo.getGender() == 1) {tv_usergender_edituserinfo.setText("男");} else {tv_usergender_edituserinfo.setText("女");}//签名tv_sign_edituserinfo.setText(CommonUtils.notNull(tempUserInfo.getSign()));}}private void initView() {layout_choose_edituserinfo.setVisibility(View.VISIBLE);layout_choose_edituserinfo.setY(mScreenHeight + getViewHeight(layout_choose_edituserinfo));}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {switch (requestCode) {case REQUEST_CAMERA:onRequestCamera(grantResults);break;case REQUEST_READ_WIRTE:onRequestWriteAndRead(grantResults);break;default:super.onRequestPermissionsResult(requestCode, permissions, grantResults);break;}}@OnClick({R.id.btn_editportrait_eidtuserinfo, R.id.btn_editnickname_eidtuserinfo,R.id.view_curtain_edituserinfo, R.id.btn_editsex_eidtuserinfo,R.id.btn_editsign_eidtuserinfo, R.id.btn_chooseclose_edituserinfo,R.id.btn_bindphonenumber_eidtuserinfo, R.id.btn_back_edituserinfo})@Overridepublic void onClick(View view) {Intent i;switch (view.getId()) {case R.id.btn_editportrait_eidtuserinfo://更改Choose框文字tv_choosetv1_edituserinfo.setText("拍照");tv_choosetv2_edituserinfo.setText("从相册选择");btn_choosebtn1_edituserinfo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//TODO 拍照getPortraitByCamera();}});btn_choosebtn2_edituserinfo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//TODO 从相册选择getPortraitByAlbum();}});ifShowChooseLayout(true);break;case R.id.btn_editsex_eidtuserinfo://更改Choose框文字tv_choosetv1_edituserinfo.setText("男");tv_choosetv2_edituserinfo.setText("女");btn_choosebtn1_edituserinfo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//TODO 转菊花//TODO 向服务器提交用户修改性别为男性Map<String, Object> updateParams = new HashMap<>();updateParams.put("gender", 1);HttpU.getInstance().post(EditUserInfoActivity.this,Config.UPDATE_USER,updateParams,null,new HttpCallback() {@Overridepublic void onResponse(String response) {LogUtils.d("EditUserInfoActivity_updategender" + response);HttpResult updateResult = JSON.parseObject(response, HttpResult.class);if (updateResult.isSuc()) {//TODO 菊花消失//TODO 显示更改名字成功//更新本地用户信息数据HttpU.getInstance().post(mContext,Config.QUERY_USER,null,null,new HttpCallback() {@Overridepublic void onResponse(String response) {HttpResult queryResult = JSON.parseObject(response, HttpResult.class);if (queryResult.isSuc()) {//更新userinfoUserInfo userInfo = JSON.parseObject(queryResult.getRs(), UserInfo.class);UserInfoManager.getInstance(mContext).saveUserInfo(userInfo);//更新uitv_usergender_edituserinfo.setText("男");ifShowChooseLayout(false);}}});} else {//TODO 显示保存失败}//TODO 菊花消失}});}});btn_choosebtn2_edituserinfo.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {//TODO 转菊花//TODO 向服务器提交用户修改性别为女性Map<String, Object> updateParams = new HashMap<>();updateParams.put("gender", 2);HttpU.getInstance().post(EditUserInfoActivity.this,Config.UPDATE_USER,updateParams,null,new HttpCallback() {@Overridepublic void onResponse(String response) {LogUtils.d("EditUserInfoActivity_updategender" + response);HttpResult updateResult = JSON.parseObject(response, HttpResult.class);if (updateResult.isSuc()) {//TODO 菊花消失//TODO 显示更改名字成功//更新本地用户信息数据HttpU.getInstance().post(mContext,Config.QUERY_USER,null,null,new HttpCallback() {@Overridepublic void onResponse(String response) {HttpResult queryResult = JSON.parseObject(response, HttpResult.class);if (queryResult.isSuc()) {//更新userinfoUserInfo userInfo = JSON.parseObject(queryResult.getRs(), UserInfo.class);UserInfoManager.getInstance(mContext).saveUserInfo(userInfo);//更新uitv_usergender_edituserinfo.setText("女");ifShowChooseLayout(false);}}});} else {//TODO 显示保存失败}//TODO 菊花消失}});}});ifShowChooseLayout(true);break;case R.id.btn_editnickname_eidtuserinfo://修改昵称i = new Intent(EditUserInfoActivity.this, EditNickNameActivity.class);startActivityForResult(i, Config.EDITUSERINFO_EDIT_USERNAME);break;case R.id.btn_editsign_eidtuserinfo://修改签名i = new Intent(EditUserInfoActivity.this, EditSignActivity.class);startActivityForResult(i, Config.EDITUSERINFO_EDIT_SIGN);break;case R.id.btn_bindphonenumber_eidtuserinfo://绑定手机号i = new Intent(EditUserInfoActivity.this, BindPhoneNumberActivity.class);startActivity(i);break;case R.id.view_curtain_edituserinfo://点击幕布ifShowChooseLayout(false);break;case R.id.btn_chooseclose_edituserinfo://点击取消ifShowChooseLayout(false);break;case R.id.btn_back_edituserinfo://点击返回onBackPressed();break;}}@Overrideprotected void initViewsAndEvents() {if ((ContextCompat.checkSelfPermission(EditUserInfoActivity.this,Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)|| (ContextCompat.checkSelfPermission(EditUserInfoActivity.this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)){ActivityCompat.requestPermissions(EditUserInfoActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_READ_WIRTE);} else {initView();initData();}}private static boolean ifshowchooselayout = false;private void ifShowChooseLayout(boolean isshow) {ifshowchooselayout = isshow;if (isshow) {//选择头像,幕布淡入,头像选择布局淡入上滑showCurtain(true);showPortraitChoose(true);} else {//点击幕布选择框消失showCurtain(false);showPortraitChoose(false);layout_choose_edituserinfo.setY(mScreenHeight + getViewHeight(layout_choose_edituserinfo));}}/*** 控制选择头像布局显示** @param isShow*/private void showPortraitChoose(boolean isShow) {if (isShow) {PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 0f,1f);PropertyValuesHolder trsX = PropertyValuesHolder.ofFloat("translationY",-1);ObjectAnimator.ofPropertyValuesHolder(layout_choose_edituserinfo, pvhX, trsX).setDuration(400).start();} else {PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f,0f);ObjectAnimator.ofPropertyValuesHolder(layout_choose_edituserinfo, pvhX).setDuration(400).start();}}/*** 控制幕布显示** @param isShow*/private void showCurtain(boolean isShow) {ObjectAnimator animator;if (isShow) {view_curtain_edituserinfo.setVisibility(View.VISIBLE);animator = ObjectAnimator.ofFloat(view_curtain_edituserinfo, "alpha", 0f, 1f);animator.setDuration(400);animator.start();} else {animator = ObjectAnimator.ofFloat(view_curtain_edituserinfo, "alpha", 1f, 0f);animator.setDuration(400);animator.start();view_curtain_edituserinfo.setVisibility(View.GONE);}}/*** 通过手机拍照,选取照片*/public void getPortraitByCamera() {if (!AndroidCompatUtils.checkSelfPermission(this, Manifest.permission.CAMERA, REQUEST_CAMERA)) {return;}localTempImgFileName = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";//先验证手机是否有sdcardString status = Environment.getExternalStorageState();if (status.equals(Environment.MEDIA_MOUNTED)) {try {File dir = new File(Environment.getExternalStorageDirectory() + "/" + Config.LOCAL_PORTRAIT_PATH);if (!dir.exists()) {dir.mkdirs();} else {//删除所有其他照片CommonUtils.deleteFile(dir);}File f = new File(dir, localTempImgFileName);/*** 如果该文件夹已经存在,则删除它,否则创建一个*/try {if (f.exists()) {f.delete();}f.createNewFile();} catch (Exception e) {e.printStackTrace();}imageUri = Uri.fromFile(f);Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);startActivityForResult(intent, Config.GET_IMAGE_VIA_CAMERA);} catch (ActivityNotFoundException e) {// TODO Auto-generated catch blockToast.makeText(EditUserInfoActivity.this, "没有找到储存目录", Toast.LENGTH_LONG).show();}} else {Toast.makeText(EditUserInfoActivity.this, "没有储存卡", Toast.LENGTH_LONG).show();}}//照片URLprivate Uri imageUri;/*** 从相册得到图片*/public void getPortraitByAlbum() {// 激活系统图库,选择一张图片Intent intent = new Intent(Intent.ACTION_PICK);intent.setType("image/*");startActivityForResult(intent, Config.GET_IMAGE_VIA_GALLERY);}public Bitmap getImageBitmap(Context context, Intent intent) {Bitmap bitmap = null;if (intent.getExtras() != null) {bitmap = (Bitmap) intent.getExtras().get("data");} else {Uri uri = intent.getData();try {bitmap = BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri));} catch (FileNotFoundException e) {e.printStackTrace();return null;}}return bitmap;}Uri tempuri;@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode == RESULT_OK) {switch (requestCode) {case Config.GET_IMAGE_VIA_CAMERA://u就是拍摄获得的原始图片的uri,下面调用选取框进行裁剪cropImage(imageUri, 300, 300, Config.PHOTO_REQUEST_CUT);break;case Config.GET_IMAGE_VIA_GALLERY://从相册选取头像Bitmap bitmapfromgallery = getImageBitmap(EditUserInfoActivity.this, data);cropImage(Uri.parse(MediaStore.Images.Media.insertImage(getContentResolver(), bitmapfromgallery, null, null)),300, 300, Config.PHOTO_REQUEST_CUT);break;case Config.EDITUSERINFO_EDIT_USERNAME://修改昵称回调if (data.getBooleanExtra("isupdate", false)) {tv_username_edituserinfo.setText(CommonUtils.notNull(UserInfoManager.getInstance(EditUserInfoActivity.this).getUserInfo().getNickName()));}isupdate = true;break;case Config.EDITUSERINFO_EDIT_SIGN://修改签名回调if (data.getBooleanExtra("isupdate", false)) {tv_sign_edituserinfo.setText(CommonUtils.notNull(UserInfoManager.getInstance(EditUserInfoActivity.this).getUserInfo().getSign()));}isupdate = true;break;case Config.PHOTO_REQUEST_CUT:Bitmap photo = null;try {if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M && data.getData() != null) {photo = BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData()));} else {// in android version lower than M your method must workphoto = data.getParcelableExtra("data");}} catch (FileNotFoundException e) {e.printStackTrace();}uploadImage(photo);break;}}super.onActivityResult(requestCode, resultCode, data);}private void uploadImage(Bitmap photo) {if (photo == null) {LogUtils.d("裁剪后的photo为空");return;}//存到本地FileOutputStream b = null;File file = new File(Config.LOCAL_PORTRAIT_CUT_PATH);if (!file.exists()) {file.mkdirs();// 创建文件夹} else {//删除文件夹下所有文件CommonUtils.deleteFile(file);}localTempImgFileName = new DateFormat().format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";String fileName = Config.LOCAL_PORTRAIT_CUT_PATH + localTempImgFileName;try {b = new FileOutputStream(fileName);photo.compress(Bitmap.CompressFormat.JPEG, 100, b);// 把数据写入文件} catch (FileNotFoundException e) {e.printStackTrace();} finally {try {b.flush();b.close();} catch (IOException e) {e.printStackTrace();}}// 上传photo到服务器,再通过更新用户信息接口上传成用户头像,再保存到本地Map<String, Object> params = new HashMap<>();params.put("imgType", "live_image");params.put("oss", true);HttpU.getInstance().uploadImages(EditUserInfoActivity.this,Config.UPLOAD_IMG,params,new File(fileName).getAbsolutePath(),null,new HttpCallback() {@Overridepublic void onResponse(String response) {LogUtils.d("EditUserInfoActivity_upload_portroit:" + response);try {HttpResult result = JSON.parseObject(response, HttpResult.class);if (result != null && result.isSuc()) {String rs = result.getRs();//调用接口更新用户数据Map<String, Object> updateParams = new HashMap<>();updateParams.put("headUrl", rs);HttpU.getInstance().post(EditUserInfoActivity.this,Config.UPDATE_USER,updateParams,null,new HttpCallback() {@Overridepublic void onResponse(String response) {LogUtils.d("EditUserInfoActivity_updateuserinfo_portroit" + response);HttpResult updateResult = JSON.parseObject(response, HttpResult.class);if (updateResult != null && updateResult.isSuc()) {//更新用户数据成功,此时刷新用户数据HttpU.getInstance().post(EditUserInfoActivity.this,Config.QUERY_USER,null,null,new HttpCallback() {@Overridepublic void onResponse(String response) {LogUtils.d("EditUserInfoActivity_queryuserinfo_portroit" + response);HttpResult queryResult = JSON.parseObject(response, HttpResult.class);if (queryResult != null && queryResult.isSuc()) {//更新userinfo//放到本地的图片地址是补全的UserInfo userInfo = JSON.parseObject(queryResult.getRs(), UserInfo.class);String portroit = Config.IMGHEADER + userInfo.getHeadUrl();userInfo.setHeadUrl(portroit);UserInfoManager.getInstance(EditUserInfoActivity.this).saveUserInfo(userInfo);//更新头像Glide.with(EditUserInfoActivity.this).load(userInfo.getHeadUrl()).into(civ_userhead_edituserinfo);//设置数据已经更新标志isupdate = true;//关闭幕布和弹框ifShowChooseLayout(false);}}});}}});}} catch (Exception e) {e.printStackTrace();LogUtils.d("recommend-d:" + e);}}});}//截取图片public void cropImage(Uri uri, int outputX, int outputY, int requestCode) {//裁剪图片意图Intent intent = new Intent("com.android.camera.action.CROP");intent.setDataAndType(uri, "image/*");intent.putExtra("crop", "true");//裁剪框的比例,1:1intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);//裁剪后输出图片的尺寸大小intent.putExtra("outputX", outputX);intent.putExtra("outputY", outputY);//图片格式intent.putExtra("outputFormat", "JPEG");intent.putExtra("noFaceDetection", true);// 取消人脸识别intent.putExtra("return-data", true);startActivityForResult(intent, requestCode);}@Overridepublic void onConfigurationChanged(Configuration config) {super.onConfigurationChanged(config);}@Overridepublic void onBackPressed() {if (ifshowchooselayout) {ifShowChooseLayout(false);} else {Intent intent = new Intent();intent.putExtra("isupdate", isupdate);EditUserInfoActivity.this.setResult(RESULT_OK, intent);EditUserInfoActivity.this.finish();super.onBackPressed();}}private void onRequestCamera(int[] grantResults) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//启动照相机getPortraitByCamera();} else {//提示用户权限没有获取ToastUtils.showToastTop(EditUserInfoActivity.this, "无法获取相机权限,请允许使用相机!");}}private void onRequestWriteAndRead(int[] grantResults) {if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {initView();initData();} else {//提示用户权限没有获取ToastUtils.showToastTop(EditUserInfoActivity.this, "无法获取读写本地相册权限,请允许使用!");}}}

使用华为nexus6p进行拍并照裁剪图片和从相册裁剪图片相关推荐

  1. 华为背锅?微博大V质疑华为P30 Pro拍月亮造假 公司称误导观众已开除

    每次华为旗舰系列公布样张都会有一些质疑之声出现.在宣传P30 Pro强大拍照能力的时候,华为展示了"拍月亮"的样张图片,让人惊叹,不过这次依然引来了一些质疑的声音. 4月13日,知 ...

  2. 售价2999元起  华为5G自拍视频旗舰nova7系列强势来袭

    4月23日,华为nova7系列正式发布,作为面向年轻人群的5G自拍视频旗舰,延续了nova"新潮派"价值主张,用强大的自拍实力.独特的设计美学.强悍的综合性能,给用户带来卓越的使用 ...

  3. android 华为裁剪全图,调用Android原生裁剪方式裁剪图片并保存

    前言 Android提供了原生的裁剪方式,并输出裁剪后的资源到相应的目录.主要有两种方式,下面我们来看看这两种方式. 由于Android10提出分区储存,我们这里为了方便暂不使用分区储存,通过使用 a ...

  4. Android 摄像头拍照显示 相册显示 图片裁剪绘制显示

    声明: 学习这个之前, 建议先学习下内容提供器. 使用的是Android系统自带的裁剪功能. 本人真机(华为荣耀9 Android8.0)测试, 先上效果图(拍照和从相册选, 一样的效果): .1. ...

  5. Android拍照相册裁剪封装

    Android拍照相册裁剪封装 先列出来需要解决问题 展示效果 注意事项 代码 参考资料 最近用到从相机/相册选择图片的功能,这个功能虽然不复杂,网上的代码也一大堆,但是考虑到可能以后别的地方也会用到 ...

  6. Android 7.0 适配 FileProvider相机 相册 裁剪的使用

    Android7.0又加了一些新的东西,例如多窗口 通知栏发消息 等等,但是这些是一些功能的改变,可以说是很炫的进步,而我要说的是FileProvider这个杀千刀的Api,先来看一下官方解释: 上面 ...

  7. 个人界面 头像 图片选择(相册,拍照)--如何调用系统的相册,裁剪并且上传

    ##需求:个人界面的,个人头像图片的切换 方式一:点击开始切换头像的pop–相册选择 二:这里有两种方式,从相册选择和直接拍照,假设现在是从相册选择选择头像 *我在pop确定的点击方法中写了一个方法- ...

  8. PHP实现将任意尺寸的图片裁剪后等比缩放到任意尺寸的透明图片上,并实现图片翻转...

    类库地址 github.com/jinqiubj/Pi- 此类库满足以下需求 将任意尺寸的图片等比缩放到任意尺寸的透明图片上,如图1是一张200*200的正方形图片. 在等比缩放的同时,此类库可根据图 ...

  9. html5头像裁剪实例,使用cropper.js裁剪头像的实例代码

    最近项目需要头像裁剪的功能,在网上找了一下,发现了github上的cropper项目还不错,借鉴了一下..用起来挺简单的,下面是我做的一个小例子: 开始先放个成品图: 下面给出前后端的代码 前端页面是 ...

最新文章

  1. 多线程:pthread_cond_wait 实现原理
  2. mysql七个模块_mysql(pymysql模块的使用,视图,触发器)
  3. Android 通过局域网udp广播自动建立socket连接
  4. 鸿蒙怎么运行安卓应用,华为:安卓生态应用可在部分鸿蒙设备上运行
  5. 多核cpu应用场景_CPU占用100%!PC卡顿原来可以这么解决:多场景多任务也流畅
  6. 分布式消息流平台:不要只想着Kafka,还有Pulsar
  7. 《Reids 设计与实现》第十六章 集群(下)
  8. BGPVRP5.0的10条选路原则,以及NE20的IBGP负载均衡
  9. 设计模式(十七)—— 迭代器模式
  10. 苹果手机充电口接触不良怎么办_用了HOU吼猴3C数码配件让手机充电口不再接触不良...
  11. PCB封装库命名规则
  12. 信息安全技术 实验3 木马及远程控制技术
  13. 产品结构图 = 产品功能结构图 + 产品信息结构图
  14. 《Python 深度学习》刷书笔记 Chapter 8 Part-2 用Keras 实现 DeepDream
  15. win10自带虚拟机好用吗_虚拟机的新选择,win10自带Hyper-V 虚拟机
  16. Python中的if __name__ == '__main__'是什么意思呢
  17. 5.spring-boot>redis配置使用
  18. 腾讯安全发布《2020年上半年手机安全报告》,揭示手机安全四大趋势
  19. Spark 数据倾斜介绍_大数据培训
  20. Unity手机游戏发热发烫优化指南与技巧

热门文章

  1. 安装和开启 魔改bbr
  2. 盒子竞争激烈 Apple TV在美仅排第三
  3. 有鱼上钩!修改游戏数据前的准备
  4. 详解Flink中yarn部署模式以及测试
  5. 英超前瞻乐.fun|体育 中秋利物浦主场对战狼队 历史交战能否延续全胜
  6. 2022中式烹调师(高级)考试题库及答案
  7. 当你写爬虫抓不到APP请求包的时候该怎么办?【高级篇-混淆导致通用Hook工具失效】
  8. 菜鸟之如何让项目跑起来(适合小白看,不是小白的不要进来看了,浪费时间)
  9. 计算机c语言的作用,计算机c语言的特性有哪些
  10. 【原创干货】6000字、22个案例详解Pandas数据分析/预处理时的实用技巧,超简单...