实现拍照上传-图片压缩-base64上传网页 亲测

 

魅族note6(android 7) png jpg测试正常

文件大小测试正常

0.文件大小349(kb)            通过Options获取到的图片大小width:450 height: 1920

新文件大小51(kb)            通过Options获取到的图片大小width:187 height: 800

1.文件大小3520(kb)            通过Options获取到的图片大小width:3120 height: 4208

新文件大小531(kb)            通过Options获取到的图片大小width:800 height: 1078

2. 文件大小197(kb)            通过Options获取到的图片大小width:640 height: 415

新文件大小198(kb)            通过Options获取到的图片大小width:640 height: 415

 

 

代码

package com.by.yuquan.app.webview;

import android.Manifest;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.by.yuquan.app.R;
import com.by.yuquan.app.base.ActivityInterface;
import com.by.yuquan.app.base.CallBackIntent;
import com.by.yuquan.app.base.baichuan.BaiChuanUtils;
import com.by.yuquan.app.base.dialog.TaoBaoQuanDaoDialog;
import com.by.yuquan.app.base.utils.Logi;
import com.by.yuquan.app.base.utils.ToastUtils;
import com.by.yuquan.app.base.zxing.android.CaptureActivity;
import com.by.yuquan.app.webview.base.JsApi;
import com.by.yuquan.app.webview.base.WebViewBaseObject1;
import com.by.yuquan.app.webview.base1.BaseWebViewActivity1;
import com.by.yuquan.app.webview.base1.CompletionHandler;
import com.by.yuquan.app.webview.base1.OnReturnValue;
import com.by.yuquan.app.webview.google.AutoTitleWebViewActiuvity;
import com.by.yuquan.app.wxapi.WXPayEntryActivity;
import com.by.yuquan.base.AppUtils;
import com.by.yuquan.base.ImageBase64;
import com.by.yuquan.base.SharedPreferencesUtils;
import com.by.yuquan.base.ZpImageUtils;
import com.tencent.smtt.sdk.WebView;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;

import static android.os.Environment.DIRECTORY_PICTURES;

public class AutoWebViewActivity1 extends BaseWebViewActivity1 implements ActivityInterface {

    //activity回调方法
    public CallBackIntent mCallBackIntent;
    private final int REQUEST_TAKE_CODE = 51;
    private final int REQ_CHOOSE = 50;
    private File mTakePhotoFile;
    private File mFileFromCamera;
    public LinearLayout topbar_layout;
    private CompletionHandler<String> albc_handler;
    private CompletionHandler<String> completeHandler;

    private static final int REQUEST_CODE_SCAN = 0x0001;
    private CompletionHandler<String> scan_handler;
    private static final String DECODED_CONTENT_KEY = "codedContent";

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        webView = findViewById(R.id.webView);
        webView.addJavascriptInterface(new AutoWebViewActivity1.InJavaScriptLocalObj(), "java_obj");
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        topbar_layout = findViewById(R.id.topbar_layout);
        int barHeight = getStateBarHeight();
        if (barHeight != 0) {
            RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, barHeight);
            topbar_layout.setLayoutParams(layoutParams);
            topbar_layout.setVisibility(View.VISIBLE);
        }
    }

    @Override
    public WebViewBaseObject1 getObjcet1() {
        return new MyWebViewBaseObject(this);
    }

    @Override
    public JsApi getObjcet2() {
        return new JsApi(this);
    }

    @Override
    public WebViewBaseObject1 getObjcet() {
        return new MyWebViewBaseObject(this);
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
            case 5:
                int taAuth = (Integer) SharedPreferencesUtils.get(this, "TBAUTH", 1);//0:不需要授权(已授权) 1:需要授权(未授权)
                if (taAuth == 0) {
                    albc_handler.complete("success");
                } else {
                    albc_handler.complete("fail");
                }
                break;
            case REQ_CHOOSE://选择图片回调
                try {
                    String imageStr = "";
                    if (resultCode == Activity.RESULT_OK) {
                        if (data != null) {
                            String dataString = data.getDataString();
                            if (dataString != null) {
                                Uri uri = Uri.parse(dataString);
//                                File imgFile = ZpImageUtils.compressImage(this, getRealPathFromURI(uri), 200, 200, 150);
                                //                            imageStr = ImageBase64.getImageStr(getRealPathFromURI(uri));
                                //                            results = new Uri[]{Uri.parse(dataString)};
                                File imgFile = new File(getRealPathFromURI(uri));
                                if (imgFile.getName().toLowerCase().contains(".jpg") || imgFile.getName().toLowerCase().contains(".png") || imgFile.getName().toLowerCase().contains(".jpeg") || imgFile.getName().toLowerCase().contains(".gif")) {
                                    compressImage(imgFile.getAbsolutePath(),AutoWebViewActivity1.this);
//                                    imgFile=new File(tmpPath);
//                                    imageStr = "data:image/jpeg;base64," + ImageBase64.fileToBase64(imgFile);
                                } else {
                                    com.by.yuquan.base.ToastUtils.show(AutoWebViewActivity1.this, "请选择图片");
                                    return ;
                                }

                            }
                        }
                    }
                  //  completeHandler.complete(imageStr);
                } catch (Exception e) {
                }
                break;
            case REQUEST_TAKE_CODE://拍照回调
                try {
                    String imageStr = "";
                    if (resultCode == Activity.RESULT_OK) {
                        if (mFileFromCamera != null) {
                            String filePath = mTakePhotoFile.getAbsolutePath();
                            // 压缩图片到指定大小
//                            File imgFile = ZpImageUtils.compressImage(this, filePath, 100, 100, 100);
                            File imgFile = new File(filePath);
                            Uri localUri = Uri.fromFile(imgFile);
                            Intent localIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, localUri);
                            this.sendBroadcast(localIntent);
                            Uri result = Uri.fromFile(imgFile);
                            if (imgFile.getName().toLowerCase().contains(".jpg") || imgFile.getName().toLowerCase().contains(".jpeg") || imgFile.getName().toLowerCase().contains(".png") || imgFile.getName().toLowerCase().contains(".gif")) {
                                compressImage(imgFile.getAbsolutePath(),AutoWebViewActivity1.this);
                            } else {
                                com.by.yuquan.base.ToastUtils.show(AutoWebViewActivity1.this, "请选择图片");
                                return ;
                            }

                        }
                    }

                } catch (Exception e) {
                }
                break;
            case REQUEST_CODE_SCAN://扫码
                if (resultCode == this.RESULT_OK) {
                    if (data != null) {
                        //返回的文本内容
                        String content = data.getStringExtra(DECODED_CONTENT_KEY);
                        //返回的BitMap图像
//                Bitmap bitmap = data.getParcelableExtra(DECODED_BITMAP_KEY);
                        if (scan_handler != null) {
                            scan_handler.complete(content);
                        }
                    }
                }
                break;
        }
    }
    long x=0;
    long y=0;
    /**
     * 压缩 图片 ,
     * @param path 绝对路径
     * @param context 对象
     * @return
     */
    private void compressImage(final String path,final Context context) {
        //500kb 最大 [由于1半]
        int maxlenth=1024*1024;
        try{
            //如果设置为空,则获取的bitmap为空,
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;//这个参数设置为true才有效,
            Bitmap bmp = BitmapFactory.decodeFile(path, options);//这里的bitmap是个空
            if (bmp == null) {//这里说明没去获取,只获取宽高参数
               // Logi.e( "通过options获取到的bitmap为空 ===");
            }

           // double g= 12.35; BigDecimal bigG=new BigDecimal(g).setScale(1, BigDecimal.ROUND_HALF_UP); //期望得到12.4

            int outHeight = options.outHeight;
            int outWidth = options.outWidth;
//          换算逻辑
//          1mb=1024*1024 byte
            long len=new File(path).length();
            Logi.i( path+" 文件大小"+len/1024+"(kb)            通过Options获取到的图片大小" + "width:" + outWidth + " height: " + outHeight);
            //如果宽大于800 按800算
            final int totalMax=800;
            if(outWidth>=totalMax){
                x=totalMax;
                y=outHeight*x/(outWidth);
            }else if(outHeight>=totalMax){
                y=totalMax;
                x=outWidth*y/(outHeight);
            }else{
                //原来尺寸
                x=outWidth;
               y=outHeight;
            }

//
//            //.divide(new BigDecimal(len)); 会Non-terminating decimal expansion; no exact representable decimal result。 所以必须要 具体多少小数点
//            BigDecimal tmp=(new BigDecimal(outWidth*maxlenth)).divide(new BigDecimal(len),2,BigDecimal.ROUND_HALF_UP);
//             x=tmp.intValue();
//            tmp=(new BigDecimal(outHeight*maxlenth)).divide(new BigDecimal(len),2,BigDecimal.ROUND_HALF_UP);
//             y=tmp.intValue();
             //防止文件少于500k 就不压缩了
//            if(maxlenth>=len){
//                x=outWidth;
//                y=outHeight;
//            }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try{
                        Bitmap bitmap = Glide.with(context)
                                .asBitmap()
                                .load(path)
                                .submit(Integer.parseInt(""+x),Integer.parseInt(""+y))
                                .get();



                        Bitmap.CompressFormat format=Bitmap.CompressFormat.PNG;
                        String ext=""+System.currentTimeMillis();
                        ext=ext.substring(ext.length()-3);//之所以要加个字符串 因为有时候bitmap.recycle()然后用户又同时上传
                        String stringImage=ext+".hash";//这里本来.jpg要跟文件一样 奈何小米android 10 删除图片会显示提示
                        //选同一张图片 连续选
                        if(path.toLowerCase().endsWith(".jpg")){
//                            stringImage=".jpg";
                            format=Bitmap.CompressFormat.JPEG;
                        }

                        final String tmpPath=path+""+stringImage;
                        FileOutputStream out = new FileOutputStream(tmpPath+"");

                        bitmap.compress(format, 100, out);
                        out.flush();
                        out.close();
                        bitmap.recycle();

                        Logi.i( tmpPath+""+"新文件大小"+new File(tmpPath+"").length()/1024+"(kb)            通过Options获取到的图片大小" + "width:" + x + " height: " + y);
                        Activity activity= (Activity) context;
                        activity.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                try{
                                    File imgFile=new File(tmpPath);
                                    String imageStr = "data:image/jpeg;base64," + ImageBase64.getImageStr(imgFile.getAbsolutePath());
                                    completeHandler.complete(imageStr);
                                    new File(tmpPath).delete();
                                }catch (Exception e){
                                    Logi.e(e);
                                }

                            }
                        });
                    }catch (Exception e){
                        Logi.e(e);
                    }
                }
            }).start();

        }catch (Exception e){
            Logi.e(e);
        }


}
//    private Bitmap compressImage(Bitmap image) {
//
//        ByteArrayOutputStream baos = new ByteArrayOutputStream();
//        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
//        int options = 100;
//        while ( baos.toByteArray().length / 1024>100) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
//            baos.reset();//重置baos即清空baos
//            image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
//            options -= 10;//每次都减少10
//        }
//        ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
//        Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
//        return bitmap;
//    }

    protected void onRestart() {
        super.onRestart();
        if (mBaseObject.payCallBack != null && WXPayEntryActivity.ERRCORD != -10) {
            if (WXPayEntryActivity.ERRCORD == 0) {
                mBaseObject.payCallBack.complete("0");
            } else {
                mBaseObject.payCallBack.complete("-1");
            }
            WXPayEntryActivity.ERRCORD = -10;
        }
    }

    @Override
    public void success() {
        try {
            //避免A标签不能点击跳转问题
            String touchFromA = "var href=document.getElementsByTagName('a');" +
                    "for(var i=0;i<href.length;i++){\n" +
                    " if(href[i].href=='' || href[i].href=='null' || href[i].href=='javascript:;' || href[i].href=='javascript:'){continue;}" +
                    "href[i].onclick=function()" +
                    "{" +
                    "window.location.href=this.getAttribute(\"href\");" +
                    "}" +
                    "};";
            webView.loadUrl("javascript:" + touchFromA + "");
            if (!TextUtils.isEmpty(injection_js)) {
                webView.loadUrl("javascript:" + injection_js + "");
            }
            webView.callHandler("deviceType", new Object[]{"android"}, new OnReturnValue<Integer>() {
                @Override
                public void onValue(Integer retValue) {

                }
            });
            //--------------
//            webView.loadUrl("javascript:window.java_obj.getSource('<head>'+" +
//                    "document.getElementsByTagName('html')[0].innerHTML+'</head>');");
        } catch (Exception e) {
        }

        try {
            webView.callHandler("getVersion", new Object[]{AppUtils.getVerName(this)}, new OnReturnValue<Integer>() {
                @Override
                public void onValue(Integer retValue) {

                }
            });
        } catch (Exception e) {
        }
    }


    @Override
    public int initInflater() {
        return R.layout.basewebviewactivity_layout1;
    }

    @Override
    public void onClick(View v) {

    }

    @Override
    public void setIsFullScreen(boolean isFullScreen) {
        if (isFullScreen) {
            topbar_layout.setVisibility(View.GONE);
        }
    }

    @Override
    public void startActivityForResultInf(Intent intent, CallBackIntent callBackIntent) {
        this.mCallBackIntent = callBackIntent;
        startActivityForResult(intent, REQUEST_TAKE_CODE);
    }

    class MyWebViewBaseObject extends WebViewBaseObject1 {
        String oauth_url = "";

        public MyWebViewBaseObject(Context context) {
            super(context);
        }

        private TaoBaoQuanDaoDialog taoBaoQuanDaoDialog;

        /**
         * 阿里百川授权
         */
        @JavascriptInterface
        public void albcAuth(Object params, CompletionHandler<String> handler) {
            albc_handler = handler;
            if (taoBaoQuanDaoDialog == null) {
                taoBaoQuanDaoDialog = new TaoBaoQuanDaoDialog(AutoWebViewActivity1.this, R.style.dialog, "由于淘宝需要对渠道加强精细化管理,邀请您进行淘宝身份认证操作,届时没有进行身份认证得,将可能无法分享推广淘宝商品功能,请您提前认证。", new TaoBaoQuanDaoDialog.OnCloseListener() {
                    @Override
                    public void onClick(Dialog dialog, boolean confirm) {
                        try {
                            oauth_url = ((JSONObject) params).getString("url");
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                        if (TextUtils.isEmpty(oauth_url)) {
                            albc_handler.complete("fail");
                            return;
                        }
                        if (confirm) {//开始认证
                            BaiChuanUtils.getInstance(AutoWebViewActivity1.this).auth(oauth_url);
                        }
                    }
                }).setTitle("淘宝渠道认证");
            }
            if (!taoBaoQuanDaoDialog.isShowing()) {
                taoBaoQuanDaoDialog.show();
            }
        }

        /**
         * 相册选择图片
         */
        @JavascriptInterface
        public void getPicture(Object params, CompletionHandler<String> handler) {
            completeHandler = handler;
            selectImage();
        }

        /**
         * 拍图片
         *
         * @param params
         */
        @JavascriptInterface
        public void getCamera(Object params, CompletionHandler<String> handler) {
            completeHandler = handler;
            takeCameraPhoto();
        }


        @JavascriptInterface
        public void FNScanner(Object parms, CompletionHandler<String> handler) {
            if (ContextCompat.checkSelfPermission(AutoWebViewActivity1.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(AutoWebViewActivity1.this, new String[]{Manifest.permission.CAMERA}, 1);
            } else {
                scan_handler = handler;
                Intent intent = new Intent(AutoWebViewActivity1.this, CaptureActivity.class);
                startActivityForResult(intent, REQUEST_CODE_SCAN);
            }
        }
    }

    /**
     * 选择照片
     */
    private void selectImage() {
        Intent intent;
        if (Build.VERSION.SDK_INT < 19) {
            intent = new Intent(Intent.ACTION_GET_CONTENT);
            intent.setType("image/*");
            startActivityForResult(intent, REQ_CHOOSE);
        } else {
            intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            Intent wrapperIntent = Intent.createChooser(intent, null);
            startActivityForResult(wrapperIntent, REQ_CHOOSE);
        }
    }

    /**
     * 拍照方案1
     */
    public void takeCameraPhoto() {
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
            ToastUtils.showCenter(this, "设备无摄像头");
            return;
        }

        String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath();

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        mFileFromCamera = new File(filePath, System.nanoTime() + ".jpg");
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTakePhotoFile));
            startActivityForResult(intent, REQUEST_TAKE_CODE);
        } else {
            try {
                mTakePhotoFile = File.createTempFile("Zp" + System.nanoTime(), ".jpg", new File(filePath));
                Uri contentUri = FileProvider.getUriForFile(this,
                        getPackageName() + ".fileProvider", mTakePhotoFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, contentUri);
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
                        | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                startActivityForResult(intent, REQUEST_TAKE_CODE);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 拍照方案2
     */
    public void takePic() {
        try {
            String state = Environment.getExternalStorageState();
            if (state.equals(Environment.MEDIA_MOUNTED)) {
                Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File mFile = new File(Environment.getExternalStoragePublicDirectory(DIRECTORY_PICTURES), "temp.jpg");
                ///storage/emulated/0/Pictures/temp.jpg
                Uri mImageUri = Uri.fromFile(mFile);
                if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
                    //content://com.example.shinelon.takephotodemo.provider/camera_photos/Pictures/temp.jpg
                    mImageUri = FileProvider.getUriForFile(this, getPackageName() + ".fileProvider", mFile);
                }
                //指定照片保存路径(SD卡),temp.jpg为一个临时文件,每次拍照后这个图片都会被替换
                cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
                cameraIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                startActivityForResult(cameraIntent, REQUEST_TAKE_CODE);
            } else {
                ToastUtils.showCenter(this, "请确认已经插入SD卡");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据uri获取真实路径
     *
     * @param contentUri
     * @return
     */
    public String getRealPathFromURI(Uri contentUri) {
        String res = null;
        String[] proj = {MediaStore.Images.Media.DATA};
        Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null);
        if (cursor.moveToFirst()) {
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            res = cursor.getString(column_index);
        }
        cursor.close();
        return res;
    }


    final class InJavaScriptLocalObj {
        @JavascriptInterface
        public void getSource(String html) {
            Log.d("html=", html);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值