Android 图片上传(头像裁切+原图原样)

2024-05-16 10:32

本文主要是介绍Android 图片上传(头像裁切+原图原样),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


还是那句话,最近项目比较忙 哭 拖了很久这篇文章终于完成了!

先看一下效果图:

(一)头像裁切、上传服务器(效果图)

一般都是有圆形显示头像的,这里我自定义了一个ImageView,页面很干净但是看着很上档次吧!

点击头像从底部弹出一个对话框,提示用户头像来自相机或者相册,这都是常规流程。

上传完成后默认的“程序员头像”换成了萌妹子

(二)普通图片上传服务器(效果图)

模仿QQ空间发动态的布局随意捏造一个界面出来

点击添加图片从底部弹出一个对话框,提示用户图片来自相机或者相册,这也都是常规流程。

上传过程中,有可能图片很大,显示一个进度圈(其实头像上传也有,只是文件小,还没显示就上传完成了大笑

上传完成后把刚才的照片亮出来显示到按钮的地方,当然大家根据需要还可以自己扩展(比如长按抖动出现删除、继续添加N张等等)


下面简单铺一下代码:

(一)头像裁切、上传服务器(代码)


这里上边的按钮是头像的点击事件,弹出底部的头像选择框,下边的按钮跳到下个页面,进行原图上传。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override    
  2. public void onClick(View v) {    
  3.     switch (v.getId()) {    
  4.     case R.id.avatarImg:// 更换头像点击事件    
  5.         menuWindow = new SelectPicPopupWindow(mContext, itemsOnClick);      
  6.         menuWindow.showAtLocation(findViewById(R.id.mainLayout),     
  7.                 Gravity.BOTTOM|Gravity.CENTER_HORIZONTAL, 00);     
  8.         break;    
  9.     case R.id.loginBtn://登录按钮跳转事件    
  10.         startActivity(new Intent(mContext, UploadActivity.class));    
  11.         break;    
  12.     
  13.     default:    
  14.         break;    
  15.     }    
  16. }    

弹出窗绑定一个按钮事件。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //为弹出窗口实现监听类      
  2. private OnClickListener itemsOnClick = new OnClickListener() {    
  3.     @Override    
  4.     public void onClick(View v) {    
  5.         menuWindow.dismiss();    
  6.         switch (v.getId()) {    
  7.         // 拍照    
  8.         case R.id.takePhotoBtn:    
  9.             Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);    
  10.             //下面这句指定调用相机拍照后的照片存储的路径    
  11.             takeIntent.putExtra(MediaStore.EXTRA_OUTPUT,     
  12.                     Uri.fromFile(new File(Environment.getExternalStorageDirectory(), IMAGE_FILE_NAME)));    
  13.             startActivityForResult(takeIntent, REQUESTCODE_TAKE);    
  14.             break;    
  15.         // 相册选择图片    
  16.         case R.id.pickPhotoBtn:    
  17.             Intent pickIntent = new Intent(Intent.ACTION_PICK, null);    
  18.             // 如果朋友们要限制上传到服务器的图片类型时可以直接写如:"image/jpeg 、 image/png等的类型"    
  19.             pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");    
  20.             startActivityForResult(pickIntent, REQUESTCODE_PICK);    
  21.             break;    
  22.         default:    
  23.             break;    
  24.         }    
  25.     }    
  26. };     

为图像选取返回的接收处理。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override    
  2. public void onActivityResult(int requestCode, int resultCode, Intent data) {    
  3.         
  4.     switch (requestCode) {    
  5.     case REQUESTCODE_PICK:// 直接从相册获取    
  6.         try {    
  7.             startPhotoZoom(data.getData());    
  8.         } catch (NullPointerException e) {    
  9.             e.printStackTrace();// 用户点击取消操作    
  10.         }    
  11.         break;    
  12.     case REQUESTCODE_TAKE:// 调用相机拍照    
  13.         File temp = new File(Environment.getExternalStorageDirectory() + "/" + IMAGE_FILE_NAME);    
  14.         startPhotoZoom(Uri.fromFile(temp));    
  15.         break;    
  16.     case REQUESTCODE_CUTTING:// 取得裁剪后的图片    
  17.         if (data != null) {    
  18.             setPicToView(data);    
  19.         }    
  20.         break;    
  21.     }    
  22.     super.onActivityResult(requestCode, resultCode, data);    
  23. }    

把图片显示出来,然后上传。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * 裁剪图片方法实现  
  3.  * @param uri  
  4.  */    
  5. public void startPhotoZoom(Uri uri) {    
  6.     Intent intent = new Intent("com.android.camera.action.CROP");    
  7.     intent.setDataAndType(uri, "image/*");    
  8.     // crop=true是设置在开启的Intent中设置显示的VIEW可裁剪    
  9.     intent.putExtra("crop""true");    
  10.     // aspectX aspectY 是宽高的比例    
  11.     intent.putExtra("aspectX"1);    
  12.     intent.putExtra("aspectY"1);    
  13.     // outputX outputY 是裁剪图片宽高    
  14.     intent.putExtra("outputX"300);    
  15.     intent.putExtra("outputY"300);    
  16.     intent.putExtra("return-data"true);    
  17.     startActivityForResult(intent, REQUESTCODE_CUTTING);    
  18. }    
  19.         
  20. /**    
  21.  * 保存裁剪之后的图片数据    
  22.  * @param picdata    
  23.  */    
  24. private void setPicToView(Intent picdata) {    
  25.     Bundle extras = picdata.getExtras();    
  26.     if (extras != null) {    
  27.         // 取得SDCard图片路径做显示    
  28.         Bitmap photo = extras.getParcelable("data");    
  29.         Drawable drawable = new BitmapDrawable(null, photo);    
  30.         urlpath = FileUtil.saveFile(mContext, "temphead.jpg", photo);    
  31.         avatarImg.setImageDrawable(drawable);    
  32.     
  33.         // 新线程后台上传服务端    
  34.         pd = ProgressDialog.show(mContext, null"正在上传图片,请稍候...");    
  35.         new Thread(uploadImageRunnable).start();    
  36.     }    
  37. }    
  38.     
  39. /**  
  40.  * 使用HttpUrlConnection模拟post表单进行文件  
  41.  * 上传平时很少使用,比较麻烦  
  42.  * 原理是: 分析文件上传的数据格式,然后根据格式构造相应的发送给服务器的字符串。  
  43.  */    
  44. Runnable uploadImageRunnable = new Runnable() {    
  45.     @Override    
  46.     public void run() {    
  47.             
  48.         if(TextUtils.isEmpty(imgUrl)){    
  49.             Toast.makeText(mContext, "还没有设置上传服务器的路径!", Toast.LENGTH_SHORT).show();    
  50.             return;    
  51.         }    
  52.             
  53.         Map<String, String> textParams = new HashMap<String, String>();    
  54.         Map<String, File> fileparams = new HashMap<String, File>();    
  55.             
  56.         try {    
  57.             // 创建一个URL对象    
  58.             URL url = new URL(imgUrl);    
  59.             textParams = new HashMap<String, String>();    
  60.             fileparams = new HashMap<String, File>();    
  61.             // 要上传的图片文件    
  62.             File file = new File(urlpath);    
  63.             fileparams.put("image", file);    
  64.             // 利用HttpURLConnection对象从网络中获取网页数据    
  65.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();    
  66.             // 设置连接超时(记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作)    
  67.             conn.setConnectTimeout(5000);    
  68.             // 设置允许输出(发送POST请求必须设置允许输出)    
  69.             conn.setDoOutput(true);    
  70.             // 设置使用POST的方式发送    
  71.             conn.setRequestMethod("POST");    
  72.             // 设置不使用缓存(容易出现问题)    
  73.             conn.setUseCaches(false);    
  74.             conn.setRequestProperty("Charset""UTF-8");//设置编码       
  75.             // 在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头    
  76.             conn.setRequestProperty("ser-Agent""Fiddler");    
  77.             // 设置contentType    
  78.             conn.setRequestProperty("Content-Type""multipart/form-data; boundary=" + NetUtil.BOUNDARY);    
  79.             OutputStream os = conn.getOutputStream();    
  80.             DataOutputStream ds = new DataOutputStream(os);    
  81.             NetUtil.writeStringParams(textParams, ds);    
  82.             NetUtil.writeFileParams(fileparams, ds);    
  83.             NetUtil.paramsEnd(ds);    
  84.             // 对文件流操作完,要记得及时关闭    
  85.             os.close();    
  86.             // 服务器返回的响应吗    
  87.             int code = conn.getResponseCode(); // 从Internet获取网页,发送请求,将网页以流的形式读回来    
  88.             // 对响应码进行判断    
  89.             if (code == 200) {// 返回的响应码200,是成功    
  90.                 // 得到网络返回的输入流    
  91.                 InputStream is = conn.getInputStream();    
  92.                 resultStr = NetUtil.readString(is);    
  93.             } else {    
  94.                 Toast.makeText(mContext, "请求URL失败!", Toast.LENGTH_SHORT).show();    
  95.             }    
  96.         } catch (Exception e) {    
  97.             e.printStackTrace();    
  98.         }    
  99.         handler.sendEmptyMessage(0);// 执行耗时的方法之后发送消给handler    
  100.     }    
  101. };    
  102.     
  103. Handler handler = new Handler(new Handler.Callback() {    
  104.         
  105.     @Override    
  106.     public boolean handleMessage(Message msg) {    
  107.         switch (msg.what) {    
  108.         case 0:    
  109.             pd.dismiss();    
  110.                 
  111.             try {    
  112.                 // 返回数据示例,根据需求和后台数据灵活处理    
  113.                 // {"status":"1","statusMessage":"上传成功","imageUrl":"http://120.24.219.49/726287_temphead.jpg"}    
  114.                 JSONObject jsonObject = new JSONObject(resultStr);    
  115.                     
  116.                 // 服务端以字符串“1”作为操作成功标记    
  117.                 if (jsonObject.optString("status").equals("1")) {    
  118.                     BitmapFactory.Options option = new BitmapFactory.Options();    
  119.                     // 压缩图片:表示缩略图大小为原始图片大小的几分之一,1为原图,3为三分之一    
  120.                     option.inSampleSize = 1;    
  121.                         
  122.                     // 服务端返回的JsonObject对象中提取到图片的网络URL路径    
  123.                     String imageUrl = jsonObject.optString("imageUrl");    
  124.                     Toast.makeText(mContext, imageUrl, Toast.LENGTH_SHORT).show();    
  125.                 }else{    
  126.                     Toast.makeText(mContext, jsonObject.optString("statusMessage"), Toast.LENGTH_SHORT).show();    
  127.                 }    
  128.                     
  129.             } catch (JSONException e) {    
  130.                 e.printStackTrace();    
  131.             }    
  132.                 
  133.             break;    
  134.                 
  135.         default:    
  136.             break;    
  137.         }    
  138.         return false;    
  139.     }    
  140. });    


(二)普通图片上传服务器(代码)

    直接从这里开始,和头像那里基本没什么区别,我把拍照什么的单独抽出了方法,思路更清晰。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //为弹出窗口实现监听类      
  2. private OnClickListener itemsOnClick = new OnClickListener() {    
  3.     @Override    
  4.     public void onClick(View v) {    
  5.         // 隐藏弹出窗口    
  6.         menuWindow.dismiss();    
  7.             
  8.         switch (v.getId()) {    
  9.         case R.id.takePhotoBtn:// 拍照    
  10.             takePhoto();    
  11.             break;    
  12.         case R.id.pickPhotoBtn:// 相册选择图片    
  13.             pickPhoto();    
  14.             break;    
  15.         case R.id.cancelBtn:// 取消    
  16.             break;    
  17.         default:    
  18.             break;    
  19.         }    
  20.     }    
  21. };     


[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * 拍照获取图片  
  3.  */    
  4. private void takePhoto() {    
  5.     // 执行拍照前,应该先判断SD卡是否存在    
  6.     String SDState = Environment.getExternalStorageState();    
  7.     if (SDState.equals(Environment.MEDIA_MOUNTED)) {    
  8.     
  9.         Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);    
  10.         /***  
  11.          * 需要说明一下,以下操作使用照相机拍照,拍照后的图片会存放在相册中的   
  12.          * 这里使用的这种方式有一个好处就是获取的图片是拍照后的原图  
  13.          * 如果不使用ContentValues存放照片路径的话,拍照后获取的图片为缩略图不清晰  
  14.          */    
  15.         ContentValues values = new ContentValues();    
  16.         photoUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);    
  17.         intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, photoUri);    
  18.         startActivityForResult(intent, SELECT_PIC_BY_TACK_PHOTO);    
  19.     } else {    
  20.         Toast.makeText(this"内存卡不存在", Toast.LENGTH_LONG).show();    
  21.     }    
  22. }    
  23.     
  24. /***  
  25.  * 从相册中取图片  
  26.  */    
  27. private void pickPhoto() {    
  28.     Intent intent = new Intent();    
  29.     // 如果要限制上传到服务器的图片类型时可以直接写如:"image/jpeg 、 image/png等的类型"    
  30.     intent.setType("image/*");    
  31.     intent.setAction(Intent.ACTION_GET_CONTENT);    
  32.     startActivityForResult(intent, SELECT_PIC_BY_PICK_PHOTO);    
  33. }   

处理一下图片选取的页面回调。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override    
  2.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {    
  3.         // 点击取消按钮    
  4.         if(resultCode == RESULT_CANCELED){    
  5.             return;    
  6.         }    
  7.             
  8.         // 可以使用同一个方法,这里分开写为了防止以后扩展不同的需求    
  9.         switch (requestCode) {    
  10.         case SELECT_PIC_BY_PICK_PHOTO:// 如果是直接从相册获取    
  11.             doPhoto(requestCode, data);    
  12.             break;    
  13.         case SELECT_PIC_BY_TACK_PHOTO:// 如果是调用相机拍照时    
  14.             doPhoto(requestCode, data);    
  15.             break;    
  16.         }    
  17.         super.onActivityResult(requestCode, resultCode, data);    
  18.     }    

接下来就是显示图片和上传服务器了,上传和头像是同一个流程,只是不进行裁切。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /**  
  2.  * 选择图片后,获取图片的路径  
  3.  *   
  4.  * @param requestCode  
  5.  * @param data  
  6.  */    
  7. private void doPhoto(int requestCode, Intent data) {    
  8.         
  9.     // 从相册取图片,有些手机有异常情况,请注意    
  10.     if (requestCode == SELECT_PIC_BY_PICK_PHOTO) {    
  11.         if (data == null) {    
  12.             Toast.makeText(this"选择图片文件出错", Toast.LENGTH_LONG).show();    
  13.             return;    
  14.         }    
  15.         photoUri = data.getData();    
  16.         if (photoUri == null) {    
  17.             Toast.makeText(this"选择图片文件出错", Toast.LENGTH_LONG).show();    
  18.             return;    
  19.         }    
  20.     }    
  21.         
  22.     String[] pojo = { MediaColumns.DATA };    
  23.     // The method managedQuery() from the type Activity is deprecated    
  24.     //Cursor cursor = managedQuery(photoUri, pojo, null, null, null);    
  25.     Cursor cursor = mContext.getContentResolver().query(photoUri, pojo, nullnullnull);    
  26.     if (cursor != null) {    
  27.         int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);    
  28.         cursor.moveToFirst();    
  29.         picPath = cursor.getString(columnIndex);    
  30.             
  31.         // 4.0以上的版本会自动关闭 (4.0--14;; 4.0.3--15)    
  32.         if (Integer.parseInt(Build.VERSION.SDK) < 14) {    
  33.             cursor.close();    
  34.         }    
  35.     }    
  36.         
  37.     // 如果图片符合要求将其上传到服务器    
  38.     if (picPath != null && (    picPath.endsWith(".png") ||     
  39.                                 picPath.endsWith(".PNG") ||     
  40.                                 picPath.endsWith(".jpg") ||     
  41.                                 picPath.endsWith(".JPG"))) {    
  42.     
  43.             
  44.         BitmapFactory.Options option = new BitmapFactory.Options();    
  45.         // 压缩图片:表示缩略图大小为原始图片大小的几分之一,1为原图    
  46.         option.inSampleSize = 1;    
  47.         // 根据图片的SDCard路径读出Bitmap    
  48.         Bitmap bm = BitmapFactory.decodeFile(picPath, option);    
  49.         // 显示在图片控件上    
  50.         picImg.setImageBitmap(bm);    
  51.             
  52.         pd = ProgressDialog.show(mContext, null"正在上传图片,请稍候...");    
  53.         new Thread(uploadImageRunnable).start();    
  54.     } else {    
  55.         Toast.makeText(this"选择图片文件不正确", Toast.LENGTH_LONG).show();    
  56.     }    
  57.     
  58. }    
  59.     
  60. /**  
  61.  * 使用HttpUrlConnection模拟post表单进行文件  
  62.  * 上传平时很少使用,比较麻烦  
  63.  * 原理是: 分析文件上传的数据格式,然后根据格式构造相应的发送给服务器的字符串。  
  64.  */    
  65. Runnable uploadImageRunnable = new Runnable() {    
  66.     @Override    
  67.     public void run() {    
  68.             
  69.         if(TextUtils.isEmpty(imgUrl)){    
  70.             Toast.makeText(mContext, "还没有设置上传服务器的路径!", Toast.LENGTH_SHORT).show();    
  71.             return;    
  72.         }    
  73.             
  74.         Map<String, String> textParams = new HashMap<String, String>();    
  75.         Map<String, File> fileparams = new HashMap<String, File>();    
  76.             
  77.         try {    
  78.             // 创建一个URL对象    
  79.             URL url = new URL(imgUrl);    
  80.             textParams = new HashMap<String, String>();    
  81.             fileparams = new HashMap<String, File>();    
  82.             // 要上传的图片文件    
  83.             File file = new File(picPath);    
  84.             fileparams.put("image", file);    
  85.             // 利用HttpURLConnection对象从网络中获取网页数据    
  86.             HttpURLConnection conn = (HttpURLConnection) url.openConnection();    
  87.             // 设置连接超时(记得设置连接超时,如果网络不好,Android系统在超过默认时间会收回资源中断操作)    
  88.             conn.setConnectTimeout(5000);    
  89.             // 设置允许输出(发送POST请求必须设置允许输出)    
  90.             conn.setDoOutput(true);    
  91.             // 设置使用POST的方式发送    
  92.             conn.setRequestMethod("POST");    
  93.             // 设置不使用缓存(容易出现问题)    
  94.             conn.setUseCaches(false);    
  95.             // 在开始用HttpURLConnection对象的setRequestProperty()设置,就是生成HTML文件头    
  96.             conn.setRequestProperty("ser-Agent""Fiddler");    
  97.             // 设置contentType    
  98.             conn.setRequestProperty("Content-Type""multipart/form-data; boundary=" + NetUtil.BOUNDARY);    
  99.             OutputStream os = conn.getOutputStream();    
  100.             DataOutputStream ds = new DataOutputStream(os);    
  101.             NetUtil.writeStringParams(textParams, ds);    
  102.             NetUtil.writeFileParams(fileparams, ds);    
  103.             NetUtil.paramsEnd(ds);    
  104.             // 对文件流操作完,要记得及时关闭    
  105.             os.close();    
  106.             // 服务器返回的响应吗    
  107.             int code = conn.getResponseCode(); // 从Internet获取网页,发送请求,将网页以流的形式读回来    
  108.             // 对响应码进行判断    
  109.             if (code == 200) {// 返回的响应码200,是成功    
  110.                 // 得到网络返回的输入流    
  111.                 InputStream is = conn.getInputStream();    
  112.                 resultStr = NetUtil.readString(is);    
  113.             } else {    
  114.                 Toast.makeText(mContext, "请求URL失败!", Toast.LENGTH_SHORT).show();    
  115.             }    
  116.         } catch (Exception e) {    
  117.             e.printStackTrace();    
  118.         }    
  119.         handler.sendEmptyMessage(0);// 执行耗时的方法之后发送消给handler    
  120.     }    
  121. };    
  122.     
  123. Handler handler = new Handler(new Handler.Callback() {    
  124.     
  125.     @Override    
  126.     public boolean handleMessage(Message msg) {    
  127.         switch (msg.what) {    
  128.         case 0:    
  129.             pd.dismiss();    
  130.                 
  131.             try {    
  132.                 JSONObject jsonObject = new JSONObject(resultStr);    
  133.                 // 服务端以字符串“1”作为操作成功标记    
  134.                 if (jsonObject.optString("status").equals("1")) {    
  135.     
  136.                     // 用于拼接发布说说时用到的图片路径    
  137.                     // 服务端返回的JsonObject对象中提取到图片的网络URL路径    
  138.                     String imageUrl = jsonObject.optString("imageUrl");    
  139.                     // 获取缓存中的图片路径    
  140.                     Toast.makeText(mContext, imageUrl, Toast.LENGTH_SHORT).show();    
  141.                 } else {    
  142.                     Toast.makeText(mContext, jsonObject.optString("statusMessage"), Toast.LENGTH_SHORT).show();    
  143.                 }    
  144.                     
  145.             } catch (JSONException e) {    
  146.                 e.printStackTrace();    
  147.             }    
  148.             break;    
  149.         default:    
  150.             break;    
  151.         }    
  152.         return false;    
  153.     }    
  154. });    


最后放上完整的代码!大家上传路径自己搭建啊!

这篇关于Android 图片上传(头像裁切+原图原样)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/994657

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Spring MVC 图片上传

引入需要的包 <dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.1</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-

Prompt - 将图片的表格转换成Markdown

Prompt - 将图片的表格转换成Markdown 0. 引言1. 提示词2. 原始版本 0. 引言 最近尝试将图片中的表格转换成Markdown格式,需要不断条件和优化提示词。记录一下调整好的提示词,以后在继续优化迭代。 1. 提示词 英文版本: You are an AI assistant tasked with extracting the content of