0
点赞
收藏
分享

微信扫一扫

springboot接受安卓传来的图片至服务器本地并被读取

精进的医生 2022-03-16 阅读 39

springboot接受安卓传来的多张图片至阿里云CentOS服务器本地并被读取

后台

参考点+依赖

多图片保存在本地服务器

参考《springboot保存图片到项目文件资源路径》
修改点:多图片保存在本地服务器的确定路径,同时压缩图片保证图片不过大导致读取服务器图片时加载过慢。

压缩

《Thumbnails 压缩后反而变大》可知,用jpg转成jpg效果最佳
使用方法

Thumbnails.of("原图存放地址")
      .scale(1f)
      .outputQuality(0.5f)
      .toFile("压缩后存放地址");

依赖:

 <!-- 压缩图片-->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
        </dependency>
<!--  图片压缩Unsupported Image Type异常 引入以下依赖可解决-->
        <dependency>
            <groupId>com.twelvemonkeys.imageio</groupId>
            <artifactId>imageio-jpeg</artifactId>
            <version>3.6</version>
        </dependency>

读取图片的方式:tomcat

参考《图片上传到Linux服务器的指定路径后,如何以外链的形式访问图片呢?》
与springboot的定义的文件目录需对应对应tomcat中添加

 <Context docBase ="/home/images/" path ="/images" debug ="0" reloadable ="true"/>

springboot

    private String staticPath="/home"; //定义上传文件的根目录
    @ResponseBody
   @RequestMapping(value ="/loadimages", method = RequestMethod.POST)
   public AnswerRet<String> uploadImageByVisits(@RequestParam("files") List<MultipartFile> files, Long id) {
       if(files==null)
           throw new RrException(55500,"file 空");
       else{
           File targetFile = new File(staticPath);
           if (!targetFile.exists()){
               targetFile.mkdirs();
           }

           StringBuffer stringBuffer=new StringBuffer();
           for(int i=0;i<files.size();i++){
         		//文件名:随机数+当前时间+格式
               Random r = new Random();
               int randomI = r.nextInt(1000);
               Date date=new Date();
               String fileName ="/"+date.getTime()+randomI+".jpg";
               String url_path = "/images"  + fileName;
               //图片保存路径
               String savePath = staticPath + url_path;
               System.out.println("图片保存地址:"+savePath);
               // 访问路径=静态资源路径+文件目录路径
               String visitPath ="http://host:端口号" + url_path;
               System.out.println("图片访问uri:"+visitPath);

               File saveFile = new File(savePath);
               if (!saveFile.exists()){
                   saveFile.mkdirs();
               }
               try {
                   files.get(i).transferTo(saveFile);  //将临时存储的文件移动到真实存储路径下
                   //压缩
                   Thumbnails.of(savePath)
                           .scale(1f)
                           .outputQuality(0.5f)
                           .toFile(savePath);
                   stringBuffer.append(visitPath+",");
               } catch (IOException e) {
                   throw new RrException(555551, e.getMessage());
               }
           }
           if(stringBuffer.length()<=1)
               throw new RrException(555550,"图片上传异常");
           String url = stringBuffer.substring(0, stringBuffer.length() - 1);
           //url 插入数据库中,读取时则得到url,由逗号隔开来查看图片

       }
       return new AnswerRet<>(1,"成功");
   }

服务器本地图片:
在这里插入图片描述

外网读取图片:
在这里插入图片描述

安卓上传多图片

效果:选择图片上传时,最多九张图片上传,点击图片可浏览,图片左上角有删除按钮,点击加号弹窗提示拍照/相册
【利用girdview展示选中的图片,在最后的位置固定为+图片,直至9张图充满girdview
在这里插入图片描述

girdview适配器

girdview的item 主要两项imageview 一个图片一个删除按钮
在适配器中装载图片并确定删除按钮点击事件:

public class PhotoChooseListAdapter  extends BaseAdapter {
   	//List<LocalMedia> 图片选择器选择后回调可返回的数据 即选中的list
   private List<LocalMedia> selectList;
   private LayoutInflater layoutInflater;
   private Context context;

   public PhotoChooseListAdapter(List<LocalMedia> selectList,Context context){
       this.selectList=selectList;
       this.context=context;
       layoutInflater = LayoutInflater.from(context);
   }
   @Override
   public int getCount() {
       return selectList.size() + 1;
   }

   @Override
   public Object getItem(int i) {
       return selectList.get(i);
   }

   @Override
   public long getItemId(int i) {
       return i;
   }

   @Override
   public View getView(int position, View view, ViewGroup viewGroup) {
       ViewHolder viewHolder = null;
       if (view == null) {
           viewHolder = new ViewHolder();
           view = layoutInflater.inflate(girdview的item, viewGroup, false);
           viewHolder.addimage = (ImageView) view.findViewById(R.id.photo_img);
           viewHolder.photo_delete=(ImageView) view.findViewById(R.id.photo_delete);
           view.setTag(viewHolder);
       } else {
           viewHolder = (ViewHolder) view.getTag();
       }
       if (position == selectList.size()) {
           //加号图标展示
           Glide.with(context)
                   .load(R.drawable.add_photo)
                   .into(viewHolder.addimage);
           if (position == 9) {
            //加号图标消失
               viewHolder.addimage.setVisibility(View.GONE);
           }
           viewHolder.photo_delete.setVisibility(View.GONE);
       } else {
           //正常展示图片,带上删除按钮
           viewHolder.photo_delete.setVisibility(View.VISIBLE);
           viewHolder.photo_delete.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view) {
                   selectList.remove(position);
                   setList(selectList);
                   notifyDataSetChanged();
               }
           });
           //图片加载
           String path;
           if (selectList.get(position).isCompressed())
               path=selectList.get(position).getCompressPath();
           else if(selectList.get(position).isCut())
               path=selectList.get(position).getCutPath();
           else
               path=selectList.get(position).getPath();
           Glide.with(context)
                   .load(path)
                   .into(viewHolder.addimage);
       }
       return  view;
   }

   public void setList(List<LocalMedia> selectList){
       this.selectList=selectList;
   }

   class ViewHolder {
       ImageView addimage;
       ImageView photo_delete;
   }
}

绑定适配器确定点击item监听事件,i==selectList.size() :点击加号按钮弹窗提示选择拍照/相册
否则 浏览图片

  // 浏览图片
PictureSelector.create(VisitsAddActivity.this)
          .themeStyle(com.luck.picture.lib.R.style.picture_default_style)
          .isNotPreviewDownload(true)//是否显示保存弹框
          .imageEngine(GlideEngine.createGlideEngine()) // 选择器展示不出图片则添加
          .openExternalPreview(i, selectList);

弹窗

弹窗出现前,需动态获取权限
依赖

    //动态获取权
    implementation 'com.github.tbruyelle:rxpermissions:0.9.0'
        final RxPermissions rxPermissions = new RxPermissions(VisitsAddActivity.this);
        rxPermissions.request(Manifest.permission.RECORD_AUDIO,Manifest.permission.WRITE_EXTERNAL_STORAGE
                ,Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE)
                .subscribe(new Action1<Boolean>() {
                    @Override
                    public void call(Boolean granted) {
                        if (granted) { // 在android 6.0之前会默认返回true
                        //打开弹窗
                        } else {
                            Toast.makeText(VisitsAddActivity.this, "拒绝", Toast.LENGTH_SHORT).show();
                        }
                    }
                });

图片选择器

参考《Android 多图选择器PictureSelector 使用》
按上述链接完成缺少依赖glide的GlideEngine
解决方法:《关于Pictureselector相册全白、不显示图片的问题(附GlideEngine代码)》
打开相册举例:
private List<LocalMedia> selectList, 存放确定后回调返回的选中的图片list,每次打开相册和拍照都要带上

            PictureSelector.create(VisitsAddActivity.this)
                    .openGallery(PictureMimeType.ofImage())
                    .selectionData(selectList)
                    .maxSelectNum(9)
                    .minSelectNum(1)
                    .imageEngine(GlideEngine.createGlideEngine())
                    .imageSpanCount(3)
                    .isPreviewImage(false)
                    .selectionMode(PictureConfig.MULTIPLE)
                    .isCamera(false)
                    .imageFormat(PictureMimeType.PNG)
                    .circleDimmedLayer(true)
                    .isEnableCrop(false)
                    .isCompress(true)
                    .showCropFrame(false)
                    .showCropGrid(false)
                    .rotateEnabled(false)
                    .scaleEnabled(true)
                    .isGif(false)
                    .minimumCompressSize(100)
                    .synOrAsy(true)
                    .forResult(PictureConfig.CHOOSE_REQUEST);

回调

PictureSelector.obtainMultipleResult(data)返回 List<LocalMedia> 即选中的图片赋值给selectList,直接动态修改gridview的高度。

发出请求

安卓请求规格化看前文 【Android】安卓实现网络请求,得到数据并显示于listview,包含token与拦截器

ApiService中

    @POST("loadimages")
    Call<ResponseBody> loadImages(@Body RequestBody requestBody);

请求调用

        MultipartBody.Builder bodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        for(int i=0;i<selectList.size();i++){
            File file=new File(selectList.get(i).getRealPath());
            selectList.get(i).getRealPath().replaceAll("\\\\", "/");
            bodyBuilder.addFormDataPart("files",file.getAbsolutePath(),
                    RequestBody.create(MediaType.parse("application/octet-stream"),
                            new File(file.getAbsolutePath())));
        }
        bodyBuilder.addFormDataPart("id",id);
        RequestBody body = bodyBuilder.build();
        Call<ResponseBody> responseBodyCall = apiServiceBusiness.uploadImageVisits(body);
        responseBodyCall.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                String res=null;
                try {
                    res=new String(response.body().bytes());
                    JSONObject jsonObject= JSON.parseObject(res);
                    if(Long.parseLong(jsonObject.get("code").toString())==1) {
                        //成功的操作
                    } else {
                      //返回码失败的操作
                    }
                }catch (IOException e){
                //读取返回数据失败的操作
                }

            }
            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                //请求失败的操作
            }
        });
举报

相关推荐

0 条评论