android短视频开发,调用相机、相册,压缩图片后上传
android短视频开发,调用相机、相册,压缩图片后上传实现的相关代码
重写webChromeClient的onShowFileChooser方法
1 | @Override <br> public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {<br> mUploadCallbackAboveL = filePathCallback;<br> openAlbum();<br> return true ;<br> } |
fileChooserParams可以接收h5中input标签的一些参数,选择好文件后,将文件uri传递给filePathCallback。
原文链接:调用原生相机、相册
选择调用相机或相册
1 | private void openAlbum() {<br> // 指定拍照存储位置的方式调起相机<br> String filePath = Environment.getExternalStorageDirectory() + File.separator<br> + Environment.DIRECTORY_PICTURES + File.separator;<br> String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";<br> image = new File(filePath + fileName);<br> imageUri = Uri.fromFile(image);<br> Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);<br> captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);<br> Intent Photo = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);<br> Intent chooserIntent = Intent.createChooser(Photo, "选择照片");<br> chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});<br> startActivityForResult(chooserIntent, REQUEST_CODE);<br> } |
通过imageUri保存调用相机拍照的照片的存储位置。用Intent打开选择相机、相册或文件夹的activity。
接收选择照片,或者拍照返回的uri
1 | @Override <br> protected void onActivityResult( int requestCode, int resultCode, Intent data) {<br> super .onActivityResult(requestCode, resultCode, data);<br> if (requestCode == REQUEST_CODE) {<br> if (mUploadCallbackAboveL != null ) {<br> chooseAbove(resultCode, data);<br> } else {<br> Toast.makeText( this , "发生错误" , Toast.LENGTH_SHORT).show();<br> }<br> }<br> } |
choosAbove方法来处理获取后的uri,并回传给filePathCallback。
处理uri
具体的处理步骤,通过uri获取到图片的path,读取图片,压缩图片后重新存储,将压缩后的图片uri进行回传
(1). chooseAbove方法
1 | private void chooseAbove( int resultCode, Intent data) {<br> if (RESULT_OK == resultCode) {<br> updatePhotos();<br> if (data != null ) {<br> // 处理选择的照片<br> Uri[] results;<br> Uri uriData = data.getData();<br> if (uriData != null) {<br> results = new Uri[]{uriData};<br> try {<br> Uri compressImageUri = ImageCompressUtils.compressBmpFromBmp(uriToString(uriData));<br> mUploadCallbackAboveL.onReceiveValue(new Uri[]{compressImageUri});<br> } catch (Exception e) {<br> e.printStackTrace();<br> requestWritePermission();<br> }<br> } else {<br> mUploadCallbackAboveL.onReceiveValue(null);<br> }<br> } else {<br>// 处理拍照的照片<br> try {<br> Uri compressImageUri = ImageCompressUtils.compressBmpFromBmp(imageUri.getPath());<br> mUploadCallbackAboveL.onReceiveValue(new Uri[]{compressImageUri});<br> } catch (Exception e) {<br> e.printStackTrace();<br> requestWritePermission();<br> }<br> }<br> } else {<br> mUploadCallbackAboveL.onReceiveValue(null);<br> }<br> mUploadCallbackAboveL = null;<br> } |
由于拍照的照片存储在imageUri,这里将拍照和相册选择分开处理,注意,如果没有选择照片,给filePathCallback传一个空值,防止上传只能点击一次后失效。
(2). 压缩图片的工具类ImageCompressUtils
原文链接图片压缩工具类(解决了压缩后图片被旋转的问题)
1 | <br> public class ImageCompressUtils {<br> /**<br> * @param srcPath<br> * @return<br> * @description 将图片从本地读到内存时,即图片从File形式变为Bitmap形式<br> * 特点:通过设置采样率,减少图片的像素,达到对内存中的Bitmao进行压缩<br> * 方法说明: 该方法就是对Bitmap形式的图片进行压缩, 也就是通过设置采样率, 减少Bitmap的像素, 从而减少了它所占用的内存<br> */ <br> public static Uri compressBmpFromBmp(String srcPath) {<br> // String srcPathStr = srcPath;<br> BitmapFactory.Options newOptions = new BitmapFactory.Options();<br> newOptions.inJustDecodeBounds = true;//只读边,不读内容<br> Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOptions);<br> newOptions.inJustDecodeBounds = false;<br> int w = newOptions.outWidth;<br> int h = newOptions.outHeight;<br> float hh = 800f;<br> float ww = 480f;<br> int be = 1;<br> if (w > h && w > ww) {<br> be = (int) (newOptions.outWidth / ww);<br> } else if (w < h && h > hh) {<br> be = (int) (newOptions.outHeight / hh);<br> }<br> if (be <= 0)<br> be = 1;<br> newOptions.inSampleSize = be;//设置采样率<br> newOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;//该模式是默认的,可不设<br> newOptions.inPurgeable = true;//同时设置才会有效<br> newOptions.inInputShareable = true;//当系统内存不够时候图片会自动被回收<br> bitmap = BitmapFactory.decodeFile(srcPath, newOptions);<br> int degree = readPictureDegree(srcPath);<br> bitmap = rotateBitmap(bitmap, degree);<br> return compressBmpToFile(bitmap);<br> }<br> /**<br> * @param bmp<br> * @description 将图片保存到本地时进行压缩, 即将图片从Bitmap形式变为File形式时进行压缩,<br> * 特点是: File形式的图片确实被压缩了, 但是当你重新读取压缩后的file为 Bitmap是,它占用的内存并没有改变<br> * 所谓的质量压缩,即为改变其图像的位深和每个像素的透明度,也就是说JPEG格式压缩后,原来图片中透明的元素将消失,所以这种格式很可能造成失真<br> */<br> public static Uri compressBmpToFile(Bitmap bmp) {<br> String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/shoppingMall/compressImgs/";<br> File file = new File(path + System.currentTimeMillis() + ".jpg");<br> //判断文件夹是否存在,如果不存在则创建文件夹<br> if (!file.getParentFile().exists()) {<br> file.getParentFile().mkdirs();<br> }<br> ByteArrayOutputStream baos = new ByteArrayOutputStream();<br> int options = 80;<br> bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);<br> while (baos.toByteArray().length / 1024 > 100) {<br> baos.reset();<br> options -= 10;<br> bmp.compress(Bitmap.CompressFormat.JPEG, options, baos);<br> }<br> try {<br> FileOutputStream fos = new FileOutputStream(file);<br> fos.write(baos.toByteArray());<br> fos.flush();<br> fos.close();<br>// copyExif(srcPathStr,file.getAbsolutePath());<br>// return file.getAbsolutePath();<br> return Uri.fromFile(file);<br> } catch (FileNotFoundException e) {<br>// TODO Auto-generated catch block<br> e.printStackTrace();<br> } catch (IOException e) {<br>// TODO Auto-generated catch block<br> e.printStackTrace();<br> }<br> return null;<br> }<br> /**<br> * 获取图片旋转角度<br> *<br> * @param srcPath<br> * @return<br> */<br> private static int readPictureDegree(String srcPath) {<br> int degree = 0;<br> try {<br> ExifInterface exifInterface = new ExifInterface(srcPath);<br> int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);<br> switch (orientation) {<br> case ExifInterface.ORIENTATION_ROTATE_90:<br> degree = 90;<br> break;<br> case ExifInterface.ORIENTATION_ROTATE_180:<br> degree = 180;<br> break;<br> case ExifInterface.ORIENTATION_ROTATE_270:<br> degree = 270;<br> break;<br> }<br> } catch (IOException e) {<br> e.printStackTrace();<br> }<br> return degree;<br> }<br> //处理图片旋转<br> private static Bitmap rotateBitmap(Bitmap bitmap, int rotate) {<br> if (bitmap == null)<br> return null;<br> int w = bitmap.getWidth();<br> int h = bitmap.getHeight();<br> // Setting post rotate to 90<br> Matrix mtx = new Matrix();<br> mtx.postRotate(rotate);<br> return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);<br> }<br>} |
调用压缩方法,将压缩后的图片的uri传递给filePathCallback,上传结束。
以上就是 android短视频开发,调用相机、相册,压缩图片后上传实现的相关代码,更多内容欢迎关注之后的文章
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现