美文网首页
图片的显示,加载,上传、下载

图片的显示,加载,上传、下载

作者: 陈科比大宝贝儿 | 来源:发表于2023-02-06 14:33 被阅读0次

一、图片显示
1、要做到图片不变形,不裁剪,正常显示,必须知道图片的宽高或者是宽高比,加载的时候,如果高度大于宽度,就先加载高度为父布局高度,宽度根据比例加载,反之一样。

  private fun setImageWidthHeight(imageView: ImageView,width:Int,height:Int){
        imageView.post {
            val params: RelativeLayout.LayoutParams = imageView.layoutParams as RelativeLayout.LayoutParams
            if (height >= width){ //撑满高度
                imageView.layoutParams.height = mImageWidth
                val tempWidth: Float = (width.toFloat()) / (height.toFloat())
                imageView.layoutParams.width = (tempWidth * mImageWidth).toInt()
                imageView.layoutParams = params
                Log.d("setImageWidthHeight", "setImageWidthHeight: 图片宽度是:${imageView.layoutParams.width},," +
                        ",高度是:${imageView.layoutParams.height}"+ ",,,,"+tempWidth)
            }else{
                imageView.layoutParams.width = mImageWidth
                val tempHeight: Float = (height.toFloat()) / (width.toFloat())
                imageView.layoutParams.height = (tempHeight * mImageWidth).toInt()
                imageView.layoutParams = params
                Log.d("setImageWidthHeight", "setImageWidthHeight: 图片宽度是:${imageView.layoutParams.width},," +
                        ",高度是:${imageView.layoutParams.height}"+ ",,,,"+tempHeight)
            }
        }
    }

或者使用约束布局,前提也是必须知道宽高比或者宽高,只有知道了宽高比,才不会压缩和变形

二、图片加载
图片的选取,压缩、显示,建议使用第三方加载库:pictureselector,里面已经适配了Android 13版本
注:GIF图片不能进行压缩,一旦压缩就变成了静态图片

三、图片上传
上传时区分类型
gif图片使用MediaType.parse("image/gif");
静态图片使用MediaType.parse("image/png");类型

  fun <T> uploadImage(
        cls: Class<T>,
        reqUrl: String,
        fileList: ArrayList<BeanImage>,
        callBack: RequestCallBack<T>
    ) {

        val params = HashMap<String, Any>()
        HttpUtils.addCommonData(params)
        val multipartBodyBuilder = MultipartBody.Builder()
        multipartBodyBuilder.setType(MultipartBody.FORM)

        //遍历map中所有参数到builder
        for (key in params.keys) {
            multipartBodyBuilder.addFormDataPart(key, params[key].toString() + "")
        }

        //遍历paths中所有图片绝对路径到builder,并约定key如“upload”作为后台接受多张图片的key
        LogUtils.d(TAG, "uploadImage: 需要上传的图片是:${fileList}")
        for (index in 0 until fileList.size) {
            val url = fileList[index].url ?: ""
            val file = File(url)
            if (!file.exists()) {
                return
            }
            val fileName = System.currentTimeMillis().toString() + "_" + file.name
            LogUtils.d(TAG, "uploadImage 文件的名称是: $fileName")
            if (fileList[index].isGif()) {
                Log.d(TAG, "uploadImage: 当前是gif图,,$fileName")
                multipartBodyBuilder.addFormDataPart(
                    "file${index}",
                    fileName,
                    file.asRequestBody(HttpUtils.MEDIA_TYPE_GIF)
                )
            } else {
                multipartBodyBuilder.addFormDataPart(
                    "file${index}",
                    fileName,
                    file.asRequestBody(HttpUtils.MEDIA_TYPE_PNG)
                )
            }
            multipartBodyBuilder.addFormDataPart("type", "1")
        }

        val builder = CacheControl.Builder()
        builder.noCache() //不使用缓存,全部走网络
        builder.noStore() //不使用缓存,也不存储缓存
        val cache: CacheControl = builder.build()
        val requestBody: RequestBody = multipartBodyBuilder.build()
        val requestBuilder = Request.Builder()
        requestBuilder.url(reqUrl)
        requestBuilder.cacheControl(cache)
        requestBuilder.post(requestBody)
        //设置header
        var headersMap: HashMap<String, String> = HashMap()
        headersMap = OKHttpExecuter.initHttpRequestHeader(headersMap)
        if (headersMap != null && headersMap.size > 0) {
            try {
                val headers: Headers = headersMap.toHeaders()
                requestBuilder.headers(headers)
            } catch (e: Exception) {
                Log.d(TAG, "uploadImage: " + e.message)
            }
        }
        val request: Request = requestBuilder.build()
        HttpUtils.client.newCall(request).enqueue(object : Callback {
            override fun onFailure(call: Call, e: IOException) {
                call.cancel()
                Log.d(TAG, "onFailure: " + e.message.toString())
                BaseUtils.getHandler().post {
                    callBack.error(e.message.toString())
                }
            }

            @Throws(IOException::class)
            override fun onResponse(call: Call, response: Response) {
                val str = response.body?.string() //图片返回json数据
                call.cancel()
            }
        })
    }

三、图片下载
图片下载保存到图库需要申请存储权限,使用XXPermissions申请权限。
保存到图库需要适配Android12分区存储,代码参考pictureselector,静态图和动态图的下载要注意区分。

    /**
     * 保存文件
     *
     * @param context  上下文
     * @param path     文件下载路径url
     * @param mimeType 文件类型
     * @param listener 结果回调监听
     */
    public static void saveLocalFile(Context context, String path, String mimeType,
                                     OnCallbackListener<String> listener) {

        PictureThreadUtils.executeByIo(new PictureThreadUtils.SimpleTask<String>() {
            @Override
            public String doInBackground() {
                try {
                    Uri uri;
                    ContentValues contentValues = new ContentValues();
                    String time = ValueOf.toString(System.currentTimeMillis());
                    if (PictureMimeType.isHasAudio(mimeType)) {
                        contentValues.put(MediaStore.Audio.Media.DISPLAY_NAME, DateUtils.getCreateFileName("AUD_"));
                        contentValues.put(MediaStore.Audio.Media.MIME_TYPE, TextUtils.isEmpty(mimeType)
                                || mimeType.startsWith(PictureMimeType.MIME_TYPE_PREFIX_VIDEO)
                                || mimeType.startsWith(PictureMimeType.MIME_TYPE_PREFIX_IMAGE) ? PictureMimeType.MIME_TYPE_AUDIO : mimeType);
                        if (SdkVersionUtils.isQ()) {
                            contentValues.put(MediaStore.Audio.Media.DATE_TAKEN, time);
                            contentValues.put(MediaStore.Audio.Media.RELATIVE_PATH, Environment.DIRECTORY_MUSIC);
                        } else {
                            File dir = TextUtils.equals(Environment.getExternalStorageState(), Environment.MEDIA_MOUNTED)
                                    ? Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)
                                    : context.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
                            contentValues.put(MediaStore.MediaColumns.DATA, dir.getAbsolutePath() + File.separator
                                    + DateUtils.getCreateFileName("AUD_") + PictureMimeType.AMR);
                        }
                        uri = context.getContentResolver().insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, contentValues);
                    } else if (PictureMimeType.isHasVideo(mimeType)) {
                        contentValues.put(MediaStore.Video.Media.DISPLAY_NAME, DateUtils.getCreateFileName("VID_"));
                        contentValues.put(MediaStore.Video.Media.MIME_TYPE, TextUtils.isEmpty(mimeType)
                                || mimeType.startsWith(PictureMimeType.MIME_TYPE_PREFIX_AUDIO)
                                || mimeType.startsWith(PictureMimeType.MIME_TYPE_PREFIX_IMAGE) ? PictureMimeType.MIME_TYPE_VIDEO : mimeType);
                        if (SdkVersionUtils.isQ()) {
                            contentValues.put(MediaStore.Video.Media.DATE_TAKEN, time);
                            contentValues.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_MOVIES);
                        } else {
                            File dir = TextUtils.equals(Environment.getExternalStorageState(), Environment.MEDIA_MOUNTED)
                                    ? Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)
                                    : context.getExternalFilesDir(Environment.DIRECTORY_MOVIES);
                            contentValues.put(MediaStore.MediaColumns.DATA, dir.getAbsolutePath() + File.separator
                                    + DateUtils.getCreateFileName("VID_") + PictureMimeType.MP4);
                        }
                        uri = context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, contentValues);
                    } else { // 如果是图片
                        contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, DateUtils.getCreateFileName("IMG_"));
                        contentValues.put(MediaStore.Images.Media.MIME_TYPE, TextUtils.isEmpty(mimeType)
                                || mimeType.startsWith(PictureMimeType.MIME_TYPE_PREFIX_AUDIO)
                                || mimeType.startsWith(PictureMimeType.MIME_TYPE_PREFIX_VIDEO) ? PictureMimeType.MIME_TYPE_IMAGE : mimeType);
                        if (SdkVersionUtils.isQ()) {
                            contentValues.put(MediaStore.Images.Media.DATE_TAKEN, time);
                            contentValues.put(MediaStore.Images.Media.RELATIVE_PATH, PictureMimeType.DCIM);
                        } else {
                            if (PictureMimeType.isHasGif(mimeType) || PictureMimeType.isUrlHasGif(path)) {
                                File dir = TextUtils.equals(Environment.getExternalStorageState(), Environment.MEDIA_MOUNTED)
                                        ? Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)
                                        : context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);
                                contentValues.put(MediaStore.MediaColumns.DATA, dir.getAbsolutePath() + File.separator
                                        + DateUtils.getCreateFileName("IMG_") + PictureMimeType.GIF);
                            }
                        }
                        //插入到图库相册
                        uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
                    }
                    if (uri != null) {
                        InputStream inputStream;
                        if (PictureMimeType.isHasHttp(path)) {
                            inputStream = new URL(path).openStream();
                        } else {
                            if (PictureMimeType.isContent(path)) {
                                inputStream = PictureContentResolver.getContentResolverOpenInputStream(context, Uri.parse(path));
                            } else {
                                inputStream = new FileInputStream(path);
                            }
                        }
                        OutputStream outputStream = PictureContentResolver.getContentResolverOpenOutputStream(context, uri);
                        boolean bufferCopy = PictureFileUtils.writeFileFromIS(inputStream, outputStream);
                        if (bufferCopy) {
                            return PictureFileUtils.getPath(context, uri);
                        }
                    }
                } catch (Exception e) {
                    Log.d("saveLocalFile", "Exception - doInBackground: " + e.getMessage());
                    PictureThreadUtils.cancel(this);
                    if (listener != null) {
                        listener.onCall("");
                    }
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            public void onSuccess(String result) {
                PictureThreadUtils.cancel(this);
                ModifyExif.setExif(context,result);

                if (listener != null) {
                    listener.onCall(result);
                }
            }

            @Override
            public void onCancel() {
                Log.d("saveLocalFile", "onCancel: " + "");
                PictureThreadUtils.cancel(this);
                if (listener != null) {
                    listener.onCall("");
                }
            }

            @Override
            public void onFail(Throwable t) {
                Log.d("saveLocalFile", "onFail: " + t.getMessage());
//                PictureThreadUtils.cancel(this);
//                if (listener != null) {
//                    listener.onCall("");
//                }
            }
        });

    }

2、坑:解决图片插入到图库时间不对的bug,系统自带的相册图库会根据图片携带的时间信息进行时间顺序排列,可以通过代码修改图片的创建时间来修改图片原始的创建时间

导入exifinterface框架,需要先申请存储权限

 implementation 'androidx.exifinterface:exifinterface:1.3.0'
   //设置exif
    public static void setExif(Context context,String filepath) {
        boolean granted = XXPermissions.isGranted(context, Permission.READ_EXTERNAL_STORAGE, Permission.WRITE_EXTERNAL_STORAGE);
        if (!granted){
            return;
        }
        LogUtils.d("ModifyExif","需要修改的图片的路径是:" + filepath);
        SimpleDateFormat lastModifiedDate = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.CHINA);

        try {
            exif = new ExifInterface(filepath);     //根据图片的路径获取图片的Exif
        } catch (IOException ex) {
            Log.e("Mine", "cannot read exif", ex);
        }
        exif.setAttribute(ExifInterface.TAG_DATETIME, lastModifiedDate.format(System.currentTimeMillis()));              //把时间写进exif
        try {
            exif.saveAttributes();         //最后保存起来
        } catch (IOException e) {
            Log.e("Mine", "cannot save exif", e);
        }
    }

相关文章

网友评论

      本文标题:图片的显示,加载,上传、下载

      本文链接:https://www.haomeiwen.com/subject/zdkdyrtx.html