精华内容
下载资源
问答
  • 图片上传 base64

    Step1:整体过程

    /**
    * 由于请求框架开始就是Xutils compile ‘org.xutils:xutils:3.3.36’ 不做更改
    * 1.第三方的图片选择器(支持选择多张图片、预览、删除等)
    * 2.onActivityResult 返回选择图片的数组
    * 3.注意:接口有2个 A接口:专门用于接受图片base64码 B接口用来上传 标题、内容和拼接的url链接
    * 4.
    * ①:将选取的图片路径的转化为base64字符串 encode()方法
    * ②:选取多张时采用计数叠加一张张的上传 每上传一张将地址进行拼接 StringBuffer()方法
    * ③:当上传图片完成时A接口结束,在调用B接口 传入对应的参数即可,图片是多张之后的url链接,要去除第一个,号否则后台解析失败 substring()方法
    */

    这里写图片描述

    上图中一共上传了9张图片,蓝色部分就是一至9张的叠加链接,一共花了9秒 当然这些图片都是很小的,如果是高清图 记着一定要压缩 否则会非常慢,因为流程非常多,容易卡死

    Step3:进入主题
    build.gradle 引入这些

    //recyclerview 展示图片的
     compile 'com.android.support:recyclerview-v7:25.3.1'
     //请求网络框架xutils
        compile 'org.xutils:xutils:3.3.36'
        //加载图片的glide
        compile 'com.github.bumptech.glide:glide:3.7.0'
        //图库选择器
        compile 'me.iwf.photopicker:PhotoPicker:0.9.5@aar'
        //压缩图片的
        compile 'com.zxy.android:tiny:0.0.6'
        //删除图片显示的snackbar
        compile 'com.android.support:design:26.0.0-alpha1

    Step4:AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest package="com.helloworld.base64demo"
              xmlns:android="http://schemas.android.com/apk/res/android">
    
        <uses-permission android:name="android.permission.INTERNET" />
    
        <application
            android:name=".AppContext"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
    
            <!-- photopicker图片选取界面 -->
            <activity
                android:name="me.iwf.photopicker.PhotoPickerActivity"
                android:theme="@style/Theme.AppCompat.NoActionBar" />
            <!-- photopicker选取图片预览删除界面 -->
            <activity
                android:name="me.iwf.photopicker.PhotoPagerActivity"
                android:theme="@style/Theme.AppCompat.NoActionBar" />
    
        </application>
    
    </manifest>
    

    Step5:4个java类

    1.AppContext
    2.MainActivity
    3.PhotoAdapter
    4.RecyclerItemClickListener

    1.

    package com.helloworld.base64demo;
    
    import android.app.Application;
    import com.zxy.tiny.Tiny;
    import org.xutils.x;
    
    
    
    public class AppContext extends Application {
    
    
        public static AppContext mInstace;
    
        @Override
        public void onCreate() {
            super.onCreate();
            /**
             * 初始化第三方库
             */
            x.Ext.init(this);
            mInstace = this;
            /**
             * 压缩的
             */
            Tiny.getInstance().getApplication();
        }
    }

    2.

    package com.helloworld.base64demo;
    
    import android.app.ProgressDialog;
    import android.content.Intent;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.support.v7.widget.OrientationHelper;
    import android.support.v7.widget.RecyclerView;
    import android.support.v7.widget.StaggeredGridLayoutManager;
    import android.util.Base64;
    import android.util.Log;
    import android.view.View;
    import android.widget.TextView;
    import android.widget.Toast;
    import com.zxy.tiny.Tiny;
    import com.zxy.tiny.callback.BitmapCallback;
    import org.json.JSONException;
    import org.json.JSONObject;
    import org.xutils.common.Callback;
    import org.xutils.http.RequestParams;
    import org.xutils.x;
    import java.io.ByteArrayOutputStream;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import me.iwf.photopicker.PhotoPicker;
    import me.iwf.photopicker.PhotoPreview;
    
    
    public class MainActivity extends AppCompatActivity {
    
    
        private RecyclerView recyclerView;
        private PhotoAdapter photoAdapter;
        private ArrayList<String> selectedPhotos = new ArrayList<>();
        //原生进度框
        private ProgressDialog progressdialog;
        private static final String TAG = "ReleaseActivity";
    
        /**
         * 图片路径
         */
        private List<String> photos;
    
        //发布标题、内容接口 (这里的链接换上自己服务器上的)
        private static final String URL = "http://110.110.110.10:8080/api/information/publicInformation";
        //上传图片的接口 专门接受base64吗
        private static final String URLIMAGE = "http://110.110.110.10:8080/api/information/uploadImage";
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            recyclerView = (RecyclerView) this.findViewById(R.id.recyclerView);
            progressdialog = new ProgressDialog(this);
            progressdialog.setMessage("正在上传,请稍后...");
    
            //发布按钮事件
            TextView release_submit = (TextView) this.findViewById(R.id.release_submit);
            release_submit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //点击后显示弹框
                    progressdialog.show();
    
                    UploadImageBase64();
                    SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日    HH:mm:ss     ");
                    Date curDate = new Date(System.currentTimeMillis());//获取当前时间
                    String str = formatter.format(curDate);
                    Log.e(TAG, "UploadImageBase6开始时间: " + str);
                }
            });
            initview();
        }
    
        private void initview() {
    
            photoAdapter = new PhotoAdapter(this, selectedPhotos);
            recyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL));
            recyclerView.setAdapter(photoAdapter);
            recyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener
                    .OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
                    if (photoAdapter.getItemViewType(position) == PhotoAdapter.TYPE_ADD) {
                        PhotoPicker.builder()
                                .setPhotoCount(9) //可选择的图片数
                                .setShowCamera(true)//是否打开相机
                                .setPreviewEnabled(false)
                                .setSelected(selectedPhotos)//选择过的图片出来在进入,默认打上勾
                                .start(MainActivity.this);
                    } else {
                        PhotoPreview.builder()
                                .setPhotos(selectedPhotos)
                                .setCurrentItem(position)
                                .start(MainActivity.this);
                    }
                }
            }));
        }
    
        /**
         * 选择了图片
         */
        private String str;
    
        private void UploadImageBase64() {
    
            //当number大于或等于图片组大小时结束,并return
            if (number >= photos.size()) {
                //代表图片上传完毕,开始发布
                if (photos.size() > 1) {
                    //图片大于1张时去除第一个,
                    str = String.valueOf(sb).substring(1, sb.length());
                } else {
                    str = String.valueOf(sb);
                }
                //请求的链接、谁发布的(一般为uid)、发布的标题、发布的内容、最后拼接的图片链接
                testUploadFile(URL, "1", "123", "456", str);
                //打印 最后拼接的图片链接
                Log.e(TAG, "UploadImageBase64图片: " + str);
                return;
            }
    
            //随便找的压缩方法 可以自己写在工具类里 不建议用第三方的
            Tiny.BitmapCompressOptions options = new Tiny.BitmapCompressOptions();
            Tiny.getInstance().source(photos.get(number)).asBitmap().withOptions(options).compress(new BitmapCallback() {
                @Override
                public void callback(boolean isSuccess, Bitmap bitmap) {
                    //A接口 请求专门上传图片的链接、每次转换时的base64字符串、
                    // 这里的2只是区别是头像上传还是朋友圈上传  可去除该参数
                    UploadFile(URLIMAGE, "1", encode(photos.get(number)), "2");
                    //打印 每张图片的base64码
                    Log.e(TAG, "callback: 压缩方法" + encode(photos.get(number)));
                }
            });
        }
    
    
        /**
         * 方法1
         */
        private String encode(String path) {
            Bitmap bitmap = BitmapFactory.decodeFile(path);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
            byte[] bytes = baos.toByteArray();
            //这里有4种模式 defalut 是不连续的 me后台接不到
            //NO_WRAP 是连续的 还有2种在这就不做解释了
            byte[] encode = Base64.encode(bytes, Base64.NO_WRAP);
            String encodeString = new String(encode);
            return encodeString;
        }
    
        //msg 请求的结果
        private String msg;
    
        /**
         * 图片上传
         */
        private void testUploadFile(String url, String userId, String title, String content, String icons) {
    
            //4个对应的参数  用户id、标题、内容、拼接的图片地址
            RequestParams params = new RequestParams(url);
            params.addBodyParameter("userId", userId);
            params.addBodyParameter("title", title);
            params.addBodyParameter("content", content);
            params.addBodyParameter("icons", icons);
            x.http().post(params, new Callback.CacheCallback<String>() {
                @Override
                public void onSuccess(String result) {
                    try {
                        JSONObject object = new JSONObject(result);
                        //返回状态
                        String status = object.optString("status");
                        //返回的消息
                        msg = object.optString("msg");
                        //成功关闭进度框
                        progressdialog.dismiss();
                        //200  说明成功
                        if (status.equals("200")) {
                            Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                            //记录从点击到结束的所花时间 (可删除)
                            SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日    HH:mm:ss     ");
                            Date curDate = new Date(System.currentTimeMillis());//获取当前时间
                            String str = formatter.format(curDate);
                            Log.e(TAG, "UploadImageBase6结束时间: " + str);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void onError(Throwable ex, boolean isOnCallback) {
                    Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                    //失败也要关闭对话框
                    progressdialog.dismiss();
                    Log.e(TAG, "onError: ");
                }
    
                @Override
                public void onCancelled(CancelledException cex) {
                    Log.e(TAG, "onCancelled: ");
                }
    
                @Override
                public void onFinished() {
                    Log.e(TAG, "onFinished456: " + msg);
                }
    
                @Override
                public boolean onCache(String result) {
                    Log.e(TAG, "onCache: ");
                    return false;
                }
            });
        }
    
        /**
         * 图片上传
         * 地址,图片集、图片名称、type(默认为2)
         */
        private int number = 0;
        private String status, data;
        private StringBuffer sb = new StringBuffer();
    
        private void UploadFile(String url, String userId, String icon, String type) {
            //专门接收base64 的接口  用户id、图片、type与上面一致 只是为了区别(可删除)
            RequestParams params = new RequestParams(url);
            params.addBodyParameter("userId", userId);
            params.addBodyParameter("icon", icon);
            params.addBodyParameter("type", type);
            x.http().post(params, new Callback.CacheCallback<String>() {
                @Override
                public void onSuccess(String result) {
                    try {
                        JSONObject object = new JSONObject(result);
                        status = object.optString("status");
                        data = object.optString("data");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void onError(Throwable ex, boolean isOnCallback) {
                    Log.e(TAG, "onError: " + status);
                }
    
                @Override
                public void onCancelled(CancelledException cex) {
                    Log.e(TAG, "onCancelled: ");
                }
    
                @Override
                public void onFinished() {
                    //说明上传成功
                    if (status.equals("200")) {
                        //当图片大于1张是,进行分隔
                        if (photos.size() > 1) {
                            sb.append("," + data);
                        } else {
                            //等于一张时不用
                            sb.append(data);
                        }
                        //每上传完一张递增加1
                        number++;
                        //在此调取上传图片接口
                        UploadImageBase64();
                    }
                    Log.e(TAG, "onFinished: " + photos.size() + "\n" + sb);
                }
    
                @Override
                public boolean onCache(String result) {
                    Log.e(TAG, "onCache: ");
                    return false;
                }
            });
        }
    
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (resultCode == RESULT_OK && (requestCode == PhotoPicker.REQUEST_CODE ||
                    requestCode == PhotoPreview.REQUEST_CODE)) {
                photos = null;
                if (data != null) {
                    //获取图片的list
                    photos = data.getStringArrayListExtra(PhotoPicker.KEY_SELECTED_PHOTOS);
                }
                //清除list
                selectedPhotos.clear();
                if (photos != null) {
                    //添加至list中
                    selectedPhotos.addAll(photos);
                }
                //刷新适配器
                photoAdapter.notifyDataSetChanged();
            }
        }
    }

    3.

    package com.helloworld.base64demo;
    
    import android.content.Context;
    import android.net.Uri;
    import android.support.v7.widget.RecyclerView;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.ImageView;
    import com.bumptech.glide.Glide;
    import java.io.File;
    import java.util.ArrayList;
    import me.iwf.photopicker.utils.AndroidLifecycleUtils;
    
    
    public class PhotoAdapter extends RecyclerView.Adapter<PhotoAdapter.PhotoViewHolder> {
    
        private ArrayList<String> photoPaths = new ArrayList<String>();
        private LayoutInflater inflater;
    
        private Context mContext;
    
        public final static int TYPE_ADD = 1;
        public final static int TYPE_PHOTO = 2;
    
        final static int MAX = 9;
    
        public PhotoAdapter(Context mContext, ArrayList<String> photoPaths) {
            this.photoPaths = photoPaths;
            this.mContext = mContext;
            inflater = LayoutInflater.from(mContext);
    
        }
    
        @Override
        public PhotoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView = null;
            switch (viewType) {
                case TYPE_ADD:
                    itemView = inflater.inflate(R.layout.item_add, parent, false);
                    break;
                case TYPE_PHOTO:
                    //包里面的
                    itemView = inflater.inflate(R.layout.__picker_item_photo, parent, false);
                    break;
            }
            return new PhotoViewHolder(itemView);
        }
    
    
        @Override
        public void onBindViewHolder(final PhotoViewHolder holder, final int position) {
    
            if (getItemViewType(position) == TYPE_PHOTO) {
                Uri uri = Uri.fromFile(new File(photoPaths.get(position)));
    
                boolean canLoadImage = AndroidLifecycleUtils.canLoadImage(holder.ivPhoto.getContext());
    
                if (canLoadImage) {
                    Glide.with(mContext)
                            .load(uri)
                            .centerCrop()
                            .thumbnail(0.1f)
                            .placeholder(R.drawable.__picker_ic_photo_black_48dp)
                            .error(R.drawable.__picker_ic_broken_image_black_48dp)
                            .into(holder.ivPhoto);
                }
            }
        }
    
    
        @Override
        public int getItemCount() {
            int count = photoPaths.size() + 1;
            if (count > MAX) {
                count = MAX;
            }
            return count;
        }
    
        @Override
        public int getItemViewType(int position) {
            return (position == photoPaths.size() && position != MAX) ? TYPE_ADD : TYPE_PHOTO;
        }
    
        public static class PhotoViewHolder extends RecyclerView.ViewHolder {
            private ImageView ivPhoto;
            private View vSelected;
    
            public PhotoViewHolder(View itemView) {
                super(itemView);
                ivPhoto = (ImageView) itemView.findViewById(R.id.iv_photo);
                vSelected = itemView.findViewById(R.id.v_selected);
                if (vSelected != null) vSelected.setVisibility(View.GONE);
            }
        }
    }

    4.

    package com.helloworld.base64demo;
    
    import android.content.Context;
    import android.support.v7.widget.RecyclerView;
    import android.view.GestureDetector;
    import android.view.MotionEvent;
    import android.view.View;
    
    /**
     * 点击事件 删除
     */
    
    public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
        private OnItemClickListener mListener;
    
        public interface OnItemClickListener {
            void onItemClick(View view, int position);
        }
    
        GestureDetector mGestureDetector;
    
        public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
            mListener = listener;
            mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
                @Override
                public boolean onSingleTapUp(MotionEvent e) {
                    return true;
                }
            });
        }
    
        @Override
        public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
            View childView = view.findChildViewUnder(e.getX(), e.getY());
            if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
                mListener.onItemClick(childView, view.getChildLayoutPosition(childView));
                return true;
            }
            return false;
        }
    
        @Override public void onTouchEvent(RecyclerView rv, MotionEvent e) {
        }
    
        @Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        }
    }
    

    step6: 2个布局

    1.activity_main.xml
    2.item_add.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
    
        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#fff"
            android:paddingBottom="12dp"
            android:paddingLeft="6dp"
            android:paddingRight="6dp"
            android:paddingTop="12dp"/>
    
    
        <TextView
            android:id="@+id/release_submit"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginBottom="70dp"
            android:layout_marginLeft="22dp"
            android:layout_marginRight="22dp"
            android:layout_marginTop="70dp"
            android:background="#666"
            android:gravity="center"
            android:text="发布"
            android:textColor="#fff"/>
    
    </LinearLayout>
    

    2.

    <?xml version="1.0" encoding="utf-8"?>
    
    <me.iwf.photopicker.widget.SquareItemLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <TextView
            android:background="@drawable/xinxi_tupian"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </me.iwf.photopicker.widget.SquareItemLayout>
    

    Step7:结束

    展开全文
  • springboot 图片上传、文件上传、 批量上传Base64图片上传 。源码

    Java做文件上传、图片上传后台方法

    利用Springboot快速搭建项目环境

    项目源码已经上传到码云:https://gitee.com/jack_party/upload 。喜欢的朋友可以支持一下。

    1. 配置文件设置保存路径、上传文件大小限制。
    #注册可访问的图片路径(打包发布后的jar文件和上传地址的file文件夹在同一层级级可以直接通过项目访问图片)
    my-file-path.access-path=file:file/uploadFile/
    #存放文件的根目录
    my-file-path.root-path=E:/file/uploadFile
    #存放图片子目录
    my-file-path.image-path=/img/
    #存放文件子目录
    my-file-path.file-path=/file/
    #单个上传文件大小
    spring.servlet.multipart.max-file-size=30MB
    #总上传文件大小
    spring.servlet.multipart.max-request-size=100MB
    
    1. pom.xml 支持
    	<dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-starter-web</artifactId>
           </dependency>
       	<dependency>
               <groupId>commons-fileupload</groupId>
               <artifactId>commons-fileupload</artifactId>
               <version>1.3.1</version>
           </dependency>
    
    1. 相关工具类 Base64工具类(图片Base64加密解密工具类)
    1. java后台代码 UploadServerController.java
    
    package com.jack.upload.controller;
    
    import com.jack.upload.entity.BaseReq;
    import com.jack.upload.utils.BASE64DecodedMultipartFile;
    import com.jack.upload.utils.BaseController;
    import com.jack.upload.utils.BaseResp;
    import com.jack.upload.utils.DateUtil;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Controller;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.File;
    import java.io.IOException;
    import java.util.*;
    
    /***
     * @Author : Jack Fang
     */
    @Controller
    @RequestMapping("/uploadService/")
    public class UploadServerController extends BaseController {
    
        private static final Logger logger = LoggerFactory.getLogger(UploadServerController.class);
    
        @Value("${my-file-path.root-path}")
        private String rootPath;
    
        @Value("${my-file-path.image-path}")
        private String imagePath;
    
        @Value("${my-file-path.file-path}")
        private String filePath;
    
        private HashMap<String, String> extMap = new HashMap<String, String>();
    
        public UploadServerController() {
            extMap.put("image", "gif,jpg,jpeg,png,bmp");
            extMap.put("flash", "swf,flv");
            extMap.put("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
            extMap.put("file", "doc,docx,xls,xlsx,ppt,pptx,htm,html,txt,zip,rar,gz,bz2");
        }
    
        /**
         * 上传单图片(文件流)
         * @param request
         * @param response
         * @return
         */
        @RequestMapping("uploadImg")
        @ResponseBody
        public BaseResp uploadImg(HttpServletRequest request, HttpServletResponse response, BaseReq req){
            try {
                Map<String, Object> outMap = upload(request, initFilePath(imagePath), "image");
                return BaseResp.success("上传成功",outMap);
            }catch (IOException e){
                e.printStackTrace();
                return BaseResp.validError("上传文件出现异常:"+e.getMessage());
            }catch (RuntimeException e){
                e.printStackTrace();
                return BaseResp.validError(e.getMessage());
            }
        }
    
        /**
         * 上传图片 Base64格式
         * @param request
         * @param response
         * @return
         */
        @RequestMapping("uploadImgBase64")
        @ResponseBody
        public BaseResp uploadImgBase64(HttpServletRequest request, HttpServletResponse response, BaseReq req){
    
            Map<String,Object> outMap = new HashMap<>();
            // 上传图片base64
            String imgBase64 = request.getParameter("base64Code");
            if (StringUtils.isEmpty(imgBase64)){	// 图像数据为空
                return BaseResp.validError("未获取到上传图片内容");
            }
            // 转型为MultipartHttpRequest:
            MultipartFile file = BASE64DecodedMultipartFile.base64ToMultipart(imgBase64);
            if (file == null) {
                imgBase64 = "data:image/png;base64,"+imgBase64;
                MultipartFile file2 = BASE64DecodedMultipartFile.base64ToMultipart(imgBase64);
                if (file2 == null) {
                    return BaseResp.validError("图片base64格式转换失败。");
                }else{
                    file = file2;
                }
            }
    
            // 创建保存路径
            String filePath = initFilePath(imagePath);
    
            String fileName = DateUtil.getFormatDate("yyyyMMddHHmmss", new Date()) + "_"
                    + new Random().nextInt(1000);
            String fileRealName = file.getOriginalFilename();// 原始名称
            String[] str = fileRealName.split("\\.");
            try {
                File uploadedFile = new File(rootPath + filePath, fileName + "." + str[str.length - 1]);
                file.transferTo(uploadedFile);
    
                String imgUrl = filePath + fileName + "." + str[str.length - 1];
                imgUrl = imgUrl.replaceAll("\\\\", "/").replaceAll("//", "/");
                outMap.put("filePath",imgUrl);
                outMap.put("fileName", fileRealName);
                return BaseResp.success("上传成功",outMap);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(e.getMessage());
                return BaseResp.paramsError("上传文件失败。");
            }
    
        }
    
        /**
         * 批量上传图片
         * @param request
         * @param response
         * @return
         */
        @RequestMapping("uploadifyImg")
        @ResponseBody
        public BaseResp uploadifyImg(HttpServletRequest request, HttpServletResponse response, BaseReq req){
            try {
            	List<Map<String,Object>> list = uploadify(request, initFilePath(imagePath), "image");
                return BaseResp.success("上传成功",list);
            }catch (IOException e){
                e.printStackTrace();
                return BaseResp.validError("上传文件出现异常:"+e.getMessage());
            }catch (RuntimeException e){
                e.printStackTrace();
                return BaseResp.validError(e.getMessage());
            }
    
        }
    
        /**
         * 上传单文件(文件流)
         * @param request
         * @param response
         * @return
         */
        @RequestMapping("uploadFile")
        @ResponseBody
        public BaseResp uploadFile(HttpServletRequest request, HttpServletResponse response, BaseReq req){
            try {
                Map<String, Object> outMap = upload(request, initFilePath(filePath), null);
                return BaseResp.success("上传成功",outMap);
            }catch (IOException e){
                e.printStackTrace();
                return BaseResp.validError("上传文件出现异常:"+e.getMessage());
            }catch (RuntimeException e){
                e.printStackTrace();
                return BaseResp.validError(e.getMessage());
            }
    
        }
    
        /**
         * 批量上传文件
         * @param request
         * @param response
         * @return
         */
        @RequestMapping("uploadifyFile")
        @ResponseBody
        public BaseResp uploadifyFile(HttpServletRequest request, HttpServletResponse response, BaseReq req){
            try{
                List<Map<String,Object>> list = uploadify(request,initFilePath(filePath),null);
                return BaseResp.success("上传成功",list);
            }catch (IOException e){
                e.printStackTrace();
                return BaseResp.validError("上传文件出现异常:"+e.getMessage());
            }catch (RuntimeException e){
                e.printStackTrace();
                return BaseResp.validError(e.getMessage());
            }
    
        }
    
        /**
         * 文件流上传
         * @param request
         * @param filePath
         * @param type 指定上传的文件类型 如:image 类型
         * @return
         */
        public Map<String,Object> upload(HttpServletRequest request,String filePath,String type)throws RuntimeException,IOException {
            Map<String,Object> map = new HashMap<>();
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            Iterator<String> it = fileMap.keySet().iterator();
    
            while (it.hasNext()) {
                String key = (String) it.next();
                MultipartFile multipartFile = (MultipartFile) fileMap.get(key);
                String fileName = DateUtil.getFormatDate("yyyyMMddHHmmss", new Date()) + "_"
                        + new Random().nextInt(1000);
                String fileRealName = multipartFile.getOriginalFilename();// 原始名称
                String[] str = fileRealName.split("\\.");
    
                if(!validateFileType(fileRealName,type)){
                    throw new RuntimeException("非法的文件类型.");
                }
                File uploadedFile = new File(rootPath + filePath, fileName + "." + str[str.length-1]);
                multipartFile.transferTo(uploadedFile);
    
                String imgUrl = filePath + fileName + "." + str[str.length - 1];
                map.put("filePath", imgUrl);
                map.put("fileName", fileRealName);
            }
            return map;
        }
    
        /**
         * 批量上传
         * @param request
         * @param filePath
         * @param type 指定上传的文件类型 如:image 类型
         * @return
         */
        public List<Map<String,Object>> uploadify(HttpServletRequest request,String filePath,String type)throws IOException,RuntimeException{
            List<Map<String,Object>> imagePathList = new ArrayList<>();
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
            Iterator<String> itValidate = fileMap.keySet().iterator();
            Iterator<String> it = fileMap.keySet().iterator();
    
            // 先验证文件类型
            while (itValidate.hasNext()) {
                String key = (String) itValidate.next();
                MultipartFile multipartFile = (MultipartFile) fileMap.get(key);
                String fileRealName = multipartFile.getOriginalFilename();// 原始名称
                // 验证上传文件类型
                if(!validateFileType(fileRealName,type)){
                    throw new RuntimeException("非法的文件类型.");
                }
            }
            while (it.hasNext()) {
                String key = (String) it.next();
                MultipartFile multipartFile = (MultipartFile) fileMap.get(key);
                String fileName = DateUtil.getFormatDate("yyyyMMddHHmmss", new Date()) + "_"
                        + new Random().nextInt(1000);
                String fileRealName = multipartFile.getOriginalFilename();// 原始名称
                String[] str = fileRealName.split("\\.");
                File uploadedFile = new File(rootPath+filePath, fileName + "." + str[str.length - 1]);
                multipartFile.transferTo(uploadedFile);
                String imgUrl = filePath + fileName + "." + str[str.length - 1];
                Map<String, Object> map = new HashMap<String, Object>();
                map.put("filePath", imgUrl);
                map.put("fileName", fileRealName);
                imagePathList.add(map);
            }
            return imagePathList;
        }
    
        /**
         * 验证上传的文件类型 是否在指定的文件类型列表中
         * @param fileName
         * @param type 指定文件类型
         * @return
         */
        public boolean validateFileType(String fileName,String type){
            String fileType = fileName.substring(fileName.lastIndexOf(".")+1).toLowerCase();
            if(type!=null){
                if(extMap.containsKey(type)){
                    String extType = extMap.get(type);
                    String extTypes[] = extType.split(",");
                    return Arrays.asList(extTypes).contains(fileType);
                }else{
                    return false;
                }
            }else{
                String extType="";
                for (String value : extMap.values()) {
                    extType = extType+","+value;
                }
                String extTypes[] = extType.split(",");
                return Arrays.asList(extTypes).contains(fileType);
            }
        }
    
        /**
         * 初始化 当天文件路径 或 文件夹
         * @param path
         */
        public String initFilePath(String path)throws RuntimeException {
            try {
                // 当天日期文件夹
                String filePath = path + DateUtil.getFormatDate("yyyyMMdd", new Date()) + "/";// 头像图片保存路径
                // 文件保存目录路径
                String savePath = rootPath + filePath;
                savePath.replaceAll("\\\\", "/").replaceAll("//", "/");
    
                // 根目录是否存在 不存在则创建
                File saveDirFile = new File(rootPath);
                if (!saveDirFile.exists()) {
                    saveDirFile.mkdirs();
                }
                // 判断当天文件夹是否存在 不存在则创建
                File dirFile = new File(savePath);
                if (!dirFile.exists()) {
                    dirFile.mkdirs();
                }
                return filePath;
            }catch (RuntimeException e){
                e.printStackTrace();
                throw new RuntimeException("创建文件异常:错误的文件路径。");
            }
        }
    
    }
    
    
    

    做个测试

    api调式工具,测试上传成功
    在这里插入图片描述
    项目查看图片
    http://localhost:8080/img/20190531/20190531084951_652.jpg
    在这里插入图片描述

    展开全文
  • 前两天在做图片上传的功能优化,发现了一个效果比较好的 JQuery 插件(H5移动前端图片批量压缩上传),看其中的介绍是使用了 base64 编码的方式进行上传 个人在使用过程中,做了简单处理,只需向后台传输 base64 编码...

    背景

    • 前两天在做图片上传的功能优化,发现了一个效果比较好的 JQuery 插件(H5移动前端图片批量压缩上传),看其中的介绍是使用了 base64 编码的方式进行上传
    • 个人在使用过程中,做了简单处理,只需向后台传输 base64 编码数据即可,然后后台进行处理,下面主要介绍我的操作流程,可做参考.

    一. 前端处理

    ①. js 代码修改

    • 本着不做过多更改的原则,在处理好页面布局后,我只是修改了源代码中的 upload() 方法.

    处理目的

    1. 将获取的 base64 编码传到后台,如果后台顺利处理完毕,会返回它的存储路径,然后我进行了多图片存储路径在页面上(隐藏域)的拼接,方面后面提交后的数据库数据存储
    2. 如果没有成功,则会返回错误提示信息
    //    图片上传,将base64的图片转成二进制对象,塞进formdata上传
        function upload(basestr, type, $li) {
            var text = window.atob(basestr.split(",")[1]);
            var buffer = new Uint8Array(text.length);
            for (var i = 0; i < text.length; i++) {
                buffer[i] = text.charCodeAt(i);
            }
            var toUrl = "{:U('Order/ajaxUploadCommentImgs')}";
            $.post(
                toUrl,
                {'basestr':basestr},
                function (res) {
                    if (res.status){
                        var imgStr = $(".imgStr").val();
                        $(".imgStr").val(imgStr+"^^"+res.message);
                    }else {
                        layer.msg(res.message);
                    }
                },'JSON'
            )
        }
    

    ②. 图片上传效果

    • 选取图片后的异步上传效果如下:

    注意事项

    1. 此时尤其注意下,向后台传输的数据是否为正确的编码 [个人开发测试时,手贱剔除了 "data:image/jpeg;base64",这一段,可不要犯同样的错误]
    2. 想要知道自己的 base64 编码是否正确,建议使用 在线转换工具 测试一下

    二. 后台处理

    ①. ajax 提交的处理接口

    • 其中会调用后面的 base64_image_content() 方法,注意下面我的 showMsg()方法,实现的功能就是向前端返回处理后的 json 数据.
    public function ajaxUploadCommentImgs(){
            $postData = I('post.');
            if(IS_AJAX && IS_POST){
                $uploadUrl =  "Public/Upload";
                $tagUrl = $this->base64_image_content($postData['basestr'],$uploadUrl);
                if ($tagUrl){
                    //TODO 将其写入数据库
                    return showMsg(1,$tagUrl);
                }else{
                    return showMsg(0,'图片上传失败!');
                }
            }else{
                return showMsg(0,"请求不合法!");
            }
        }
    

    ②. 核心函数 base64_image_content

        /**
         * [将Base64图片转换为本地图片并保存]
         * @param $base64_image_content [要保存的Base64]
         * @param $path [要保存的路径]
         * @return bool|string
         */
        public function base64_image_content($base64_image_content,$path){
            //匹配出图片的格式
            if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){
                $type = $result[2];
                $new_file = $path."/".date('Ymd',time())."/";
                $basePutUrl = C('UPLOAD_IMG_BASE64_URL').$new_file;
    
                if(!file_exists($basePutUrl)){
                    //检查是否有该文件夹,如果没有就创建,并给予最高权限
                    mkdir($basePutUrl, 0700);
                }
                $ping_url = genRandomString(8).time().".{$type}";
                $ftp_image_upload_url = $new_file.$ping_url;
                $local_file_url = $basePutUrl.$ping_url;
    
                if (file_put_contents($local_file_url, base64_decode(str_replace($result[1], '', $base64_image_content)))){
    			//TODO 个人业务的FTP 账号图片上传
                ftp_upload(C('REMOTE_ROOT').$ftp_image_upload_url,$local_file_url);
                return $ftp_image_upload_url;
                }else{
                    return false;
                }
            }else{
                return false;
            }
        }
    
    • 代码中提及到的配置数据:

    //为了获取绝对路径
    ‘UPLOAD_IMG_BASE64_URL’ => str_replace(‘Application/Common/Conf/config.php’, ‘’, str_replace(’\’, ‘/’, FILE)),

    提示说明:

    ①. 说明:

    • 尤其说明一下,方法 file_put_contents()所要传入的 local_file_url 参数要求为绝对路径,不然会报错的啊啊啊啊啊,本人也是卡住了好半天!!!
    • 对于图片上传的 base64 编码上传,前端除了效果设计,处理逻辑相对是类似的,目的就是向后台传输规范的 base64 编码

    ②. 注意事项:

    本文中所提供的 Jquery 插件,测试可支持 iphone7 微信内置浏览效果以及谷歌浏览器的使用,确定就是没有提供取消按钮
    所以,异步图片数据的上传可能返回信息有延迟,以至于图片路径还未返回,就进行了整体表单的数据提交,造成数据遗失.

    ③. 附录代码

    • showMsg() 方法展示,用于 json 数据的返回
    /**
     * 公用的方法  进行信息的提示
     */
    function showMsg($status, $message, $data = array())
    {
        $result = array(
            'status' => $status,
            'message' => $message,
            'data' => $data
        );
        exit(json_encode($result));
    }
    
    展开全文
  • 公司要求图片上传转换base64位并转换为字符串,多张图片用逗号隔开,无奈只能自己二次封装element的上传组件 主要修改这几个方面 1.转换多张图片为base64, 2.去除el-upload动画, 3.支持传递最多可上传数量达到数量...

    公司要求图片上传转换base64位并转换为字符串,多张图片用逗号隔开,无奈只能自己二次封装element的上传组件

    主要修改这几个方面
    1.转换多张图片为base64,
    2.去除el-upload动画,
    3.支持传递最多可上传数量达到数量隐藏上传按钮

    这是二次封装组件的子组件代码

    pic为处理好后传递给父组件的base64代码
    limit为接受父组件传递进来的图片最多上传张数,达到最多数量隐藏上传按钮,传递0或者不传递这个参数为无限制

    <template>
      <div>
        <!-- 上传组件 -->
        <el-upload
          :class="{ hide: hideUploadEdit }"
          list-type="picture-card"
          action=""
          accept=".jpg, .png"
          :limit="limit"
          :auto-upload="false"
          :file-list="fileList"
          :on-change="getFile"
          :on-preview="handlePictureCardPreview"
          :on-remove="handleUploadRemove"
        >
          <i class="el-icon-plus"></i>
        </el-upload>
        <!-- 预览弹窗 -->
        <el-dialog :visible.sync="dialogVisible" append-to-body>
          <img width="100%" :src="dialogImageUrl" alt />
        </el-dialog>
      </div>
    </template>
    
    <script>
    export default {
      props: {
        // 可上传图片数量
        limit: {
          type: Number,
          default: 0,
        },
      },
      data() {
        return {
          // 上传按钮显示开关
          hideUploadEdit: false,
          // 上传照片列表数据
          fileList: [],
          // 预览弹窗开关
          dialogVisible: false,
          // 预览图片url
          dialogImageUrl: "",
          // 转换base64后的数据
          picArray: [],
          // 转换为字符串后的base64数据
          pic: "",
        };
      },
      watch: {
        picArray() {
          // 达到限制数量隐藏上传按钮
          this.hideUploadEdit = this.picArray.length == this.limit;
          // picArray发生变化转换为字符串
          this.pic = this.picArray.toString();
          // 传递处理好的图片数据
          this.$emit("onPicChange", this.pic);
        },
      },
      methods: {
        // 获取文件信息
        getFile(file, fileList) {
          this.picArray = [];
          for (let item of fileList) {
            this.getBase64(item.raw).then((res) => {
              this.picArray.push(res);
            });
          }
        },
        // 获取图片转base64
        getBase64(file) {
          return new Promise(function (resolve, reject) {
            const reader = new FileReader();
            let imgResult = "";
            reader.readAsDataURL(file);
            reader.onload = function () {
              imgResult = reader.result;
            };
            reader.onerror = function (error) {
              reject(error);
            };
            reader.onloadend = function () {
              resolve(imgResult);
            };
          });
        },
        // 删除
        handleUploadRemove(file, fileList) {
          this.getFile(file, fileList);
        },
        // 预览
        handlePictureCardPreview(file) {
          this.dialogImageUrl = file.url;
          this.dialogVisible = true;
        },
      },
    };
    </script>
    
    <style>
    .hide .el-upload--picture-card {
      display: none;
    }
    .el-upload-list__item {
      transition: none;
    }
    </style>
    

    下面为在父组件的用法

    1.进行实例化引用子组件,之前普通引用总是报错

    components: { upload: () => import("@/components/upload") },
    

    2.@onPicChange为接受子组件传递过来的pic数据(处理好的base64字符串)
    :limit为最多可上传的图片数量

    <!-- 图片上传组件 -->
    <upload @onPicChange="onPicChange" :limit="3"></upload>
    

    3.接收图片上传数据,保存到哪里自己安排吧

    // 接收图片上传数据
        onPicChange(pic) {
          console.log(pic);
        },
    
    展开全文
  • AJAX 的 H5移动开发Ajax上传多张Base64格式图片到服务器废话不多说,直接看代码吧1、上传组件 2、展示添加上的图片viewimg($event) {//获取当前的input标签var currentObj = event.currentTarget;//找到要预览的图片...
  • 1.基于element-ui的多文件上传并存于后端文件夹 这里我们需要用到element-ui中的upload上传upload组件 a:element-ui的安装与使用 (1) 在cmd的vue项目路径或Visual Studio Code的终端下执行 npm i element-ui -S...
  • 实现图片批量上传,可以直接使用input type=file 加上multiple 就可以实现,至于有些图片显示有问题可以通过newFileReader() 方法,将图片转换成base64直接显示2.androidandroid 默认不支持图片的批量上传,当选择图片...
  • <template> <el-upload ... :multiple="true" //是否支持多选文件 :limit="5" //最大允许上传个数 accept="image/png, image/jpeg" //接受上传的文件类型 :on-change="(file,fileList) =>.
  • 最近遇到一个项目,接口中有需要上传图片的字段,它是以图片base64编码格式的形式传递的。(Base64目前主要用于HTML5、移动开发等不考虑IE6的场景中。)请求报文示例如下: 关于如何测试实现的问题: 1)如何对图片...
  • asp.net mvc请移步mvc文件上传支持批量上传,拖拽以及预览,文件内容校验 本篇内容主要解决.net core中文件上传的问题 开发环境:ubuntu+vscode 1.导入所需要的包:nuget install bootstrap-fileinput 注意:这里...
  • 工作中经常需要用到图片上传功能,传统的存服务器目录方式在服务器迁移、部署和各种平台交互时操作不太方便,而图片资源存数据库是相对比较方便维护的方式了!以下贴出用C#存储和读取图片资源的一些方法: /* -----...
  • 网站中的上传相信大家都不陌生,也算是一个小小的技术难点,尤其时在asp.net中,上传的一些大小限制以及上传的进度的控制,以及用户体验等方面,今天在这里分享一个在asp.net mvc模式下的文件上传,同样适用于其它...
  • 需要用上插件:axupimgs插件作者:莫若卿支持版本:5.0.4+支持语言:仅中文插件版本:1.6一、axupimgs 插件作用:这是一个tinymce多图片批量上传插件,支持拖拽文件添加,拖拽支持白名单,自动过滤非白名单文件类型...
  • 最近在公司开发一个项目,其中涉及到一个工能,主要是上传一些小图片,而且在网站上需要大量引用这个小图片的,对于上传一些小的头像等。一开始觉得直接上传就好了,但是发现这样子的话,一个小图片就会发送一个http...
  • webuploader主要用来做文件的上传,支持批量上传和图片预览,图片预览是将图片生成base64数据直接在标签中使用,所以能够达到的效果是未真正上传图片可以先看到上传的效果。更多具体的介绍,可以上webuploader的官方...
  • # 是否支持批量上传 (默认值 true) servlet: multipart: enabled: true # 上传文件的临时目录 (一般情况下不用特意修改) location: # 上传文件最大为 1M (默认值 1M 根据自身业务自行控制即可) max-file...
  • CkEditor批量上传图片(java)

    千次阅读 2016-12-27 16:48:45
    最近,因后台编辑需要,原来的editor不能批量上传图片(拖拽)和上传视频,于是我花了大概一周时间研究了一下ckeditor,是现实图片拖拽上传(可多个)和视频上传(flv,mp4,mov等),开始是想将这两个功能点写在一起...
  • 图片转64位图 说明 支持JEG,PNG,SVG等图片格式转换 拖拽图片转换 图片批量转换 无需上传服务器,Canvas转换 更新记录 1.0 基础版本 1.1 加入ZeroClipboard,一键复制64位图代码。
  • 对于大量的文件上传问题来说,单个上传文件耗时耗力,而批量上传则符合用户需求。 而在实际的业务中,批量上传图片前后需要处理的东西特别多,而批量上传图片的功能则是一个重要的技术点,自己研究了半天才将其功能...
  • java利用SWFUpload实现文件批量上传

    千次阅读 2015-04-11 23:44:52
    之前在网上找过很多相关资料,很多所谓的批量上传都是忽悠人的,真正的批量上传指的是用户一次性可以选择多个文件,然后上传是将所有选取的文件上传到服务器。java中真正可以实现批量上传的技术大致有两种:一种是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,440
精华内容 3,376
关键字:

base64支持批量上传