【问题标题】:Android video and image resizingAndroid 视频和图像大小调整
【发布时间】:2015-05-21 17:33:01
【问题描述】:

我正在寻找一种方法来降低图像和视频的大小,然后再将它们上传到服务器,目前我正在发送太大的文件,我似乎找不到任何解决方案来压缩文件,我知道像whatsapp和facebook这样的应用程序可以在几秒钟内压缩视频并将它们切成90%的大小,任何人都得到建议,我将不胜感激。

谢谢。

【问题讨论】:

  • 这是一个有点过于宽泛的问题,我的假设是 Facebook 和 Whatsapp 使用或编写图像/压缩器,用于更改压缩比或编解码器类型等文件属性。跨度>
  • 你知道我如何使用一些库来实现与它们类似的东西吗?如果是这样,你会指点我那个图书馆吗?谢谢

标签: android image video compression


【解决方案1】:

您可以使用开源视频库 ffmpeg 进行压缩。

请注意,视频压缩通常是计算密集型的,因此除了小视频外,它不太可能只花费“几秒钟”。

有多种方法可以在您的应用程序中包含 ffmpeg。查看这些“包装器”项目,了解以太坊使用的示例或帮助您构建自己的 ffmpeg 库:

作为示例,一旦您选择或构建了 ffmpeg 包装器,以下代码将压缩 mp4 视频文件(默认压缩)(此代码使用自定义 ffmpeg 库,但它应该为您提供概述,您应该能够替换上述示例之一):

public class VideoCompressionTask extends AsyncTask<String, String, String> {
/* This Class is an AsynchTask to compress a video on a background thread
 * 
 */

@Override
protected String doInBackground(String... params) {
    //Compress the video in the background

    //Get the the path of the video to compress
    String videoPath;
    String videoFileName;
    File videoFileToCompress;
    if (params.length == 1) {
        videoPath = params[0];
        videoFileToCompress = new File(videoPath);
        videoFileName = videoFileToCompress.getName();
    } else {
        //One or all of the params are not present - log an error and return
        Log.d("VideoCompressionTask","doInBackground wrong number of params");
        return null;
    }

    //Make sure the video to compress actually exists
    if(!videoFileToCompress.exists()) {
        Log.d("VideoCompressionTask","doInBackground video file to compress does not exist");
        return null;
    }

    //If the compressed file already exists then delete it first and let this task create a new one
    File compressedVideoFile = new File(compressedFilePath);
    if(compressedVideoFile.exists()) {
        compressedVideoFile.delete();
    }

    String argv[] = {"ffmpeg", "-i", videoPath, "-strict", "experimental", "-acodec", "aac", compressedFilePath};
    int ffmpegWrapperreturnCode = FfmpegJNIWrapper.call_ffmpegWrapper(appContext, argv);
    Log.d("VideoCompressionTask","doInBackground ffmpegWrapperreturnCode: " + ffmpegWrapperreturnCode);

    return(compressedFilePath);
}

【讨论】:

    【解决方案2】:

    我今天有确切的需求,所以想出了这个代码。向此函数发送位图,它将返回压缩图像的文件路径(本地)。然后使用返回的文件路径创建一个 File 对象并将其发送到服务器:

     public File compressImage(Bitmap bmp) {
            Bitmap scaledBitmap = null;
    
            int actualHeight = bmp.getHeight();
            int actualWidth = bmp.getWidth();
    
    //      max Height and width values of the compressed image is taken as 816x612
            float imgRatio = actualWidth / actualHeight;
            float maxRatio = logoMaxWidth / logoMaxHeight;
    //      width and height values are set maintaining the aspect ratio of the image
            if (actualHeight > logoMaxHeight || actualWidth > logoMaxWidth) {
                if (imgRatio < maxRatio) {
                    imgRatio = logoMaxHeight / actualHeight;
                    actualWidth = (int) (imgRatio * actualWidth);
                    actualHeight = (int) logoMaxHeight;
                } else if (imgRatio > maxRatio) {
                    imgRatio = logoMaxWidth / actualWidth;
                    actualHeight = (int) (imgRatio * actualHeight);
                    actualWidth = (int) logoMaxWidth;
                } else {
                    actualHeight = (int) logoMaxHeight;
                    actualWidth = (int) logoMaxWidth;
                }
            }
            try {
                scaledBitmap = Bitmap.createScaledBitmap(bmp, actualWidth, actualHeight, true);
            } catch (OutOfMemoryError exception) {
                logoUploadFaied();
                exception.printStackTrace();
            }
            String uriSting = (System.currentTimeMillis() + ".jpg");
            File file = new File(Environment.getExternalStorageDirectory()
                    + File.separator + uriSting);
            try {
                file.createNewFile();
            } catch (IOException e) {
                logoUploadFaied();
                e.printStackTrace();
            }
    
            FileOutputStream fos = null;
            try {
                fos = new FileOutputStream(file);
            } catch (FileNotFoundException e) {
                logoUploadFaied();
                e.printStackTrace();
            }
            try {
                fos.write(getBytesFromBitmap(scaledBitmap));
                fos.close();
                //recycling bitMap to overcome OutOfMemoryError
                if(scaledBitmap!=null){
                    scaledBitmap.recycle();
                    scaledBitmap=null;
                }
            } catch (IOException e) {
                logoUploadFaied();
                e.printStackTrace();
            }
            return file;
        }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多