Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何生成适当的缩放位图以更快地将其上载到服务器?_Android_Image Uploading_Android Bitmap - Fatal编程技术网

Android 如何生成适当的缩放位图以更快地将其上载到服务器?

Android 如何生成适当的缩放位图以更快地将其上载到服务器?,android,image-uploading,android-bitmap,Android,Image Uploading,Android Bitmap,目前我正在使用mulitpart/formdata将图像上传到服务器。在node.js服务器端,图像的存储没有任何问题。但是把照片上传到服务器上要花很多时间。我试图在上传位图之前重新缩放位图,但在大多数情况下,图片上传的大小都比原始图片的大小大,比如ex-200kb的图片会变成400kb的大小。所以,我想知道如何正确缩放位图,并以高效的速度将它们以高质量上传到服务器? 位图缩放代码: bmp = MediaStore.Images.Media.getBitmap(ctx.getContentRe

目前我正在使用
mulitpart/formdata
将图像上传到服务器。在node.js服务器端,图像的存储没有任何问题。但是把照片上传到服务器上要花很多时间。我试图在上传位图之前重新缩放位图,但在大多数情况下,图片上传的大小都比原始图片的大小大,比如ex-200kb的图片会变成400kb的大小。所以,我想知道如何正确缩放位图,并以高效的速度将它们以高质量上传到服务器?

位图缩放代码:

bmp = MediaStore.Images.Media.getBitmap(ctx.getContentResolver(), uri);
                    int maxSize=700;
                    int outWidth;
                    int outHeight;
                    int inWidth = bmp.getWidth();
                    int inHeight = bmp.getHeight();
                    if(inWidth > inHeight){
                        outWidth = maxSize;
                        outHeight = (inHeight * maxSize) / inWidth;
                    } else {
                        outHeight = maxSize;
                        outWidth = (inWidth * maxSize) / inHeight;
                    }

                    final Bitmap new_bitmap = Bitmap.createScaledBitmap(bmp, outWidth, outHeight, false);
正在将位图保存到存储器:

void saveImage(String imgName, Bitmap bm) throws IOException {
    //Create Path to save Image
    File file_path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES + "/Infinity"); //Creates app specific folder
    file_path.mkdirs();
    File imageFile = new File(file_path, imgName + ".png"); // Imagename.png
    FileOutputStream out = new FileOutputStream(imageFile);
    try {
        bm.compress(Bitmap.CompressFormat.PNG, 100, out); // Compress Image
        out.flush();
        out.close();


        // Tell the media scanner about the new file so that it is
        // immediately available to the user.
        MediaScannerConnection.scanFile(ctx, new String[]{imageFile.getAbsolutePath()}, null, new MediaScannerConnection.OnScanCompletedListener() {
            public void onScanCompleted(String pathi, Uri uri) {
                Log.i("ExternalStorage", "Scanned " + file_path + ":");
                Log.i("ExternalStorage", "-> uri=" + uri);

                parts.add(prepareFilePart("photo", pathi));

                    RequestBody description = createPartFromString(obji.toString());

                    FileUploadService service = ServiceGenerator.createService(FileUploadService.class);

                    Call<ResponseBody> call = service.uploadMultipleFilesDynamic(description, parts);

                    call.enqueue(new Callback<ResponseBody>() {
                        @Override
                        public void onResponse(Call<ResponseBody> call,
                                               Response<ResponseBody> response) {
                            Log.v("Upload", "success");

                            Intent i=new Intent(ctx,Home_Screen.class);
                            i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NO_ANIMATION);
                            startActivity(i);
                        }

                        @Override
                        public void onFailure(Call<ResponseBody> call, Throwable t) {
                            if(t.getMessage()!=null) {
                                Log.e("Upload error:", t.getMessage());
                                Toast.makeText(ctx, t.getMessage(), Toast.LENGTH_LONG).show();
                                //Don't toast t.getMessage it would show the ip address which is bad
                            }
                        }
                    });

                    //Toast.makeText(ctx, "Downloaded Successfully", Toast.LENGTH_SHORT).show();

            }
        });
    } catch (Exception e) {
        throw new IOException();
    }
}
void saveImage(字符串imgName,位图bm)引发IOException{
//创建保存图像的路径
File File_path=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES+“/Infinity”);//创建特定于应用程序的文件夹
文件_path.mkdirs();
File imageFile=新文件(文件路径,imgName+“.png”);//Imagename.png
FileOutputStream out=新的FileOutputStream(imageFile);
试一试{
bm.compress(Bitmap.CompressFormat.PNG,100,out);//压缩图像
out.flush();
out.close();
//告诉媒体扫描程序有关新文件的信息,以便
//用户可立即使用。
MediaScannerConnection.scanFile(ctx,新字符串[]{imageFile.getAbsolutePath()},null,新MediaScannerConnection.OnScanCompletedListener(){
已完成的公共void(字符串路径,Uri){
Log.i(“外部存储”,“扫描”+文件路径+”:”;
Log.i(“外部存储”,“->uri=“+uri”);
添加(准备部分(“照片”,路径i));
RequestBody description=createPartFromString(obji.toString());
FileUploadService=ServiceGenerator.createService(FileUploadService.class);
Call Call=service.uploadMultipleFileDynamic(描述,部分);
call.enqueue(新回调(){
@凌驾
公共void onResponse(调用,
回应(回应){
Log.v(“上传”、“成功”);
意向i=新意向(ctx,主屏幕类);
i、 setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NO_动画);
星触觉(i);
}
@凌驾
失败时公共无效(调用调用,可丢弃的t){
如果(t.getMessage()!=null){
Log.e(“上传错误:,t.getMessage());
Toast.makeText(ctx,t.getMessage(),Toast.LENGTH_LONG.show();
//不要toast t.getMessage它将显示坏的ip地址
}
}
});
//Toast.makeText(ctx,“下载成功”,Toast.LENGTH_SHORT.show();
}
});
}捕获(例外e){
抛出新IOException();
}
}

这里有一种压缩图像的方法。首先将要压缩的图像路径发送到此方法。它将返回压缩图像路径,然后从该路径生成文件并上载

public static String compressImage(String filePath) {
        try {
            //String filePath = getRealPathFromURI(imageUri);
            Bitmap scaledBitmap = null;
            BitmapFactory.Options options = new BitmapFactory.Options();
            //by setting this field as true, the actual bitmap pixels are not loaded in the memory. Just the bounds are loaded. If
            //you try the use the bitmap here, you will get null.
            options.inJustDecodeBounds = true;
            Bitmap bmp = BitmapFactory.decodeFile(filePath, options);
        int actualHeight = options.outHeight;
        int actualWidth = options.outWidth;

        //max Height and width values of the compressed image is taken as 816x612
        float maxHeight = 816.0f;
        float maxWidth = 612.0f;
        float imgRatio = actualWidth / actualHeight;
        float maxRatio = maxWidth / maxHeight;

        //width and height values are set maintaining the aspect ratio of the image
        if (actualHeight > maxHeight || actualWidth > maxWidth) {
            if (imgRatio < maxRatio) {
                imgRatio = maxHeight / actualHeight;
                actualWidth = (int) (imgRatio * actualWidth);
                actualHeight = (int) maxHeight;
            } else if (imgRatio > maxRatio) {
                imgRatio = maxWidth / actualWidth;
                actualHeight = (int) (imgRatio * actualHeight);
                actualWidth = (int) maxWidth;
            } else {
                actualHeight = (int) maxHeight;
                actualWidth = (int) maxWidth;
            }
        }

        //setting inSampleSize value allows to load a scaled down version of the original image
        options.inSampleSize = calculateInSampleSize(options, actualWidth, actualHeight);
        //inJustDecodeBounds set to false to load the actual bitmap
        options.inJustDecodeBounds = false;
        //this options allow android to claim the bitmap memory if it runs low on memory
        options.inPurgeable = true;
        options.inInputShareable = true;
        options.inTempStorage = new byte[16 * 1024];
        try {
            //load the bitmap from its path
            bmp = BitmapFactory.decodeFile(filePath, options);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();
        }
        try {
            scaledBitmap = Bitmap.createBitmap(actualWidth, actualHeight, Bitmap.Config.ARGB_8888);
        } catch (OutOfMemoryError exception) {
            exception.printStackTrace();
        }

        float ratioX = actualWidth / (float) options.outWidth;
        float ratioY = actualHeight / (float) options.outHeight;
        float middleX = actualWidth / 2.0f;
        float middleY = actualHeight / 2.0f;

        Matrix scaleMatrix = new Matrix();
        scaleMatrix.setScale(ratioX, ratioY, middleX, middleY);

        Canvas canvas = new Canvas(scaledBitmap);
        canvas.setMatrix(scaleMatrix);
        canvas.drawBitmap(bmp, middleX - bmp.getWidth() / 2, middleY - bmp.getHeight() / 2, new Paint(Paint.FILTER_BITMAP_FLAG));

        //check the rotation of the image and display it properly
        ExifInterface exif;
        try {
            exif = new ExifInterface(filePath);
            int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
            Log.d("EXIF", "Exif: " + orientation);
            Matrix matrix = new Matrix();
            if (orientation == 6) {
                matrix.postRotate(90);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 3) {
                matrix.postRotate(180);
                Log.d("EXIF", "Exif: " + orientation);
            } else if (orientation == 8) {
                matrix.postRotate(270);
                Log.d("EXIF", "Exif: " + orientation);
            }
            scaledBitmap = Bitmap.createBitmap(scaledBitmap, 0, 0,
                    scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix,
                    true);
        } catch (IOException e) {
            e.printStackTrace();
        }

        FileOutputStream out = null;
        //String filename = getFilename();
        String filename = getFilename();
        try {
            out = new FileOutputStream(filename);
            //write the compressed bitmap at the destination specified by filename.
            scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 80, out);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        return filename;
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    return null;
}
公共静态字符串压缩图像(字符串文件路径){
试一试{
//字符串filePath=getRealPathFromURI(imageUri);
位图缩放位图=空;
BitmapFactory.Options=new-BitmapFactory.Options();
//通过将此字段设置为true,实际位图像素不会加载到内存中。只加载边界。如果
//如果您尝试在此处使用位图,将得到null。
options.inJustDecodeBounds=true;
位图bmp=BitmapFactory.decodeFile(文件路径,选项);
int实际高度=options.outHeight;
int actualWidth=options.outWidth;
//压缩图像的最大高度和宽度值为816x612
浮动最大高度=816.0f;
浮动最大宽度=612.0f;
浮动高度=实际宽度/实际高度;
浮点最大比值=最大宽度/最大高度;
//设置宽度和高度值以保持图像的纵横比
如果(实际高度>最大高度| |实际宽度>最大宽度){
if(imgRatiomaxRatio){
imgRatio=最大宽度/实际宽度;
实际高度=(int)(imgRatio*实际高度);
实际宽度=(int)最大宽度;
}否则{
实际高度=(int)最大高度;
实际宽度=(int)最大宽度;
}
}
//设置inSampleSize值允许加载原始图像的缩小版本
options.inSampleSize=calculateInSampleSize(选项、实际宽度、实际高度);
//inJustDecodeBounds设置为false以加载实际位图
options.inJustDecodeBounds=false;
//此选项允许android在内存不足时声明位图内存
options.inpurgable=true;
options.inInputShareable=true;
options.inTempStorage=新字节[16*1024];
试一试{
//从位图路径加载位图
bmp=BitmapFactory.decodeFile(文件路径,选项);
}捕获(OutOfMemoryError异常){
异常。printStackTrace();
}
试一试{
scaledbimat=Bitmap.createBitmap(实际宽度、实际高度、Bitmap.Config.ARGB_8888);
}捕获(OutOfMemoryError异常){
例外
private uploadPostImage(String imagePath) throws Exception {
    String orientation = "Portrait";
    Bitmap bm = null;
    try {
        bm = checkForRotation(imagePath);
        if (bm.getHeight() > bm.getWidth()) {
            orientation = "Portrait";
        } else if (bm.getWidth() > bm.getHeight()) {
            orientation = "Landscape";
        } else {
            orientation = "Portrait";
        }
    } catch (Exception e) {
        Log.e(e.getClass().getName(), e.getMessage());
    }
    if(bm.getWidth()>1000)
    {
        bm = getResizedBitmap(bm,1000);
    }

    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG, 100, bos);
        byte[] data = bos.toByteArray();

        /*
        /....
           Multipart uploading work
        ..../   
        */

    } catch (Exception e) {
        Log.e(e.getClass().getName(), e.getMessage());
    }
}

public Bitmap checkForRotation(String filename) {

    Bitmap bitmap = BitmapFactory.decodeFile(filename);
    int tmpHeight, tmpWidth;
    tmpWidth = bitmap.getWidth();
    tmpHeight = bitmap.getHeight();
    if (tmpWidth > tmpHeight)
    {
        tmpWidth = 1000;
        tmpHeight = (bitmap.getHeight() * tmpWidth) / bitmap.getWidth();
    } else
    {
        tmpHeight = 1000;
        tmpWidth = (bitmap.getWidth() * tmpHeight) / bitmap.getHeight();
    }
    bitmap= Bitmap.createScaledBitmap(bitmap, tmpWidth, tmpHeight, true);

    ExifInterface ei = null;
    try {
        ei = new ExifInterface(filename);
        new ExifInterface(filename);
    } catch (IOException e) {
        e.printStackTrace();
    }
    int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
            ExifInterface.ORIENTATION_NORMAL);

    switch (orientation) {
    case ExifInterface.ORIENTATION_ROTATE_90:
        bitmap = rotateImage(bitmap, 90);
        break;
    case ExifInterface.ORIENTATION_ROTATE_180:
        bitmap = rotateImage(bitmap, 180);
        break;
    }
    return bitmap;
}

public Bitmap getResizedBitmap(Bitmap bm, int newWidth) {
    int width = bm.getWidth();
    int height = bm.getHeight();

    float ratio  = (float)width/(float)height;
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float)newWidth/ratio) / height;

    // CREATE A MATRIX FOR THE MANIPULATION
    Matrix matrix = new Matrix();
    // RESIZE THE BIT MAP
    matrix.postScale(scaleWidth, scaleHeight);
    // RECREATE THE NEW BITMAP
    Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
            matrix, false);
    return resizedBitmap;
}