2015-05-21 103 views
0

我正在寻找一种方法来降低图像和视频的大小,然后将其上传到服务器,此刻我发送的文件太大,我似乎找不到任何解决方案如何压缩这些文件,我知道像whatsapp和facebook这样的应用可以在几秒钟内压缩视频,并将它们剪裁成90%的大小,任何人都可以得到建议,我会很感激的。Android视频和图像调整大小

谢谢。

+0

这是一个有点过于宽泛的问题在这里,我的假设是Facebook和Whatsapp使用或写入一个图像/压缩器,他们用来改变文件属性,如压缩比或编解码器类型。 – hoss

+0

你知道我如何使用一些图书馆来实现类似他们的东西吗?如果是这样,你可能会指向我的图书馆吗?谢谢 –

回答

2

我今天确实需要这么想这个代码。发送此函数一个位图,它将返回压缩图像的文件路径(本地)。然后创建一个与返回的文件路径的文件对象,并将其发送到服务器:

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; 
    } 
+0

谢谢你,看起来非常好! –

+0

现在我只需要找到视频压缩 –

+0

高兴地帮忙!视频压缩可能会非常棘手。你可以从这里开始http://stackoverflow.com/questions/15950610/video-compression-on-android-using-new-mediacodec-library – Kay

2

可以使用的ffmpeg,一个开源的视频库,做压缩。

请注意,视频压缩的计算密集程度通常很高,所以除了小视频之外,不可能只需要“几秒钟”。

有许多方法可以在您的应用程序中包含ffmpeg。在这些“包装”项目看一看的例子醚的使用或帮助您构建自己的ffmpeg库:

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

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); 
} 
+0

谢谢你的代码对我来说非常有用。 – MathaN