我正在开发一个应用程序,用户可以将图像从相机上传到事件,我按照通常的方式进行,但是当我根据Exif界面进行旋转时,我有时会得到OOM错误,这真的令人沮丧,我决定尝试使用JniBitmapOperations library 这似乎工作正常(我不会得到OOM错误)但是当试图旋转图像时它会变得腐败并搞砸了:/ heres图片
如您所见,上面的图片旋转到正确的位置,但都已损坏 下面的一个是原来的
这是相关代码的一部分:
Options options = new Options();
options.inJustDecodeBounds = true;
options.inPreferredConfig = Config.ARGB_8888;
Bitmap srcBitmap = BitmapFactory.decodeFile(tempImageFilePath, options);
options.inSampleSize = calculateInSampleSize(options);
options.inJustDecodeBounds = false;
srcBitmap = BitmapFactory.decodeFile(tempImageFilePath, options);
ImageLoader.getInstance().clearMemoryCache();
ImageLoader.getInstance().clearDiscCache();
final JniBitmapHolder bitmapHolder = new JniBitmapHolder(srcBitmap);
//if we comment this part out, the image comes out fine but not rotated correctly
switch (angleFix) {
case 90:
bitmapHolder.rotateBitmapCw90();
break;
case 180:
bitmapHolder.rotateBitmapCw90();
bitmapHolder.rotateBitmapCw90();
break;
case 270:
bitmapHolder.rotateBitmapCcw90();
break;
}
srcBitmap = bitmapHolder.getBitmapAndFree();
//this is the old way which caused OOM errors occasionally
// Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), m, true);
try {
FileOutputStream out = new FileOutputStream(tempImageFilePath);
srcBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
if (srcBitmap != null) {
GetImageUploadUrl getUrl = new GetImageUploadUrl();
getUrl.execute();
}
}
}
我将不胜感激任何帮助!
答案 0 :(得分:1)
我现在已经更新了代码。现在应该可以了。
我很抱歉这个错误。我确定我以前修过它。我现在已经添加了旋转180度的功能,这样你就不需要旋转两次(效率更高一些)。
并且只是说示例代码并非一无是处,这里是一个更好的示例代码。
它将覆盖您的所有相机图像,并以3种方式中的任何一种旋转它们,并将结果文件放入Android / data / PACKAGE_NAME。
这是代码:
public class MainActivity extends Activity
{
@Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final File picFolder=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
final int screenWidth=getResources().getDisplayMetrics().widthPixels;
final int screenHeight=getResources().getDisplayMetrics().heightPixels;
final File outputDir=getExternalFilesDir(null);
final ProgressDialog progressDialog=ProgressDialog.show(this,"please wait","processing");
new AsyncTask<Void,Void,Void>()
{
@Override
protected Void doInBackground(final Void... params)
{
final File[] listFiles=outputDir.listFiles((FileFilter)null);
for(final File file : listFiles)
file.delete();
final List<String> imageFilesPaths=new ArrayList<String>();
getPicturesPaths(picFolder.getAbsolutePath(),imageFilesPaths);
final JniBitmapHolder bitmapHolder=new JniBitmapHolder();
int i=0;
final Options options=new Options();
for(final String filePath : imageFilesPaths)
{
options.inJustDecodeBounds=true;
options.inPreferredConfig=Config.ARGB_8888;
prepareForDownsampling(options,screenWidth,screenHeight);
Bitmap b=BitmapFactory.decodeFile(filePath,options);
bitmapHolder.storeBitmap(b);
b.recycle();
switch(i++%3)
{
case 0:
bitmapHolder.rotateBitmapCw90();
break;
case 1:
bitmapHolder.rotateBitmap180();
break;
case 2:
bitmapHolder.rotateBitmapCcw90();
break;
}
b=bitmapHolder.getBitmapAndFree();
final File imageFile=new File(outputDir.getAbsoluteFile()+File.separator+System.currentTimeMillis()+".jpg");
imageFile.getParentFile().mkdirs();
FileOutputStream stream=null;
try
{
stream=new FileOutputStream(imageFile);
b.compress(CompressFormat.JPEG,80,stream);
stream.flush();
stream.close();
}
catch(final Exception e)
{
e.printStackTrace();
}
finally
{
if(stream!=null)
try
{
stream.close();
}
catch(final IOException e)
{
e.printStackTrace();
}
}
}
return null;
}
@Override
protected void onPostExecute(final Void result)
{
super.onPostExecute(result);
progressDialog.dismiss();
finish();
}
}.execute();
}
private static void prepareForDownsampling(final Options bitmapOptions,final int reqWidth,final int reqHeight)
{
final int inSampleSize=calculateInSampleSize(bitmapOptions,reqWidth,reqHeight);
// as much as possible, use google's way to downsample:
bitmapOptions.inSampleSize=1;
bitmapOptions.inDensity=1;
bitmapOptions.inTargetDensity=1;
bitmapOptions.inJustDecodeBounds=false;
while(bitmapOptions.inSampleSize*2<=inSampleSize)
bitmapOptions.inSampleSize*=2;
// if google's way to downsample isn't enough, do some more :
if(bitmapOptions.inSampleSize!=inSampleSize)
{
// downsample by bitmapOptions.inSampleSize/originalSampleSize .
bitmapOptions.inTargetDensity=bitmapOptions.inSampleSize;
bitmapOptions.inDensity=inSampleSize;
}
}
public static int calculateInSampleSize(final BitmapFactory.Options options,final int reqWidth,final int reqHeight)
{
final int height=options.outHeight;
final int width=options.outWidth;
int inSampleSize=1;
if(height>reqHeight||width>reqWidth)
{
final int heightRatio=Math.round((float)height/(float)reqHeight);
final int widthRatio=Math.round((float)width/(float)reqWidth);
inSampleSize=heightRatio<widthRatio ? heightRatio : widthRatio;
}
return Math.max(inSampleSize,1);
}
private static void getPicturesPaths(final String path,final List<String> filesPaths)
{
final Options options=new Options();
options.inJustDecodeBounds=true;
File f=new File(path);
if(f.isFile())
{
BitmapFactory.decodeFile(path,options);
if(options.outHeight>=0&&options.outWidth>=0)
filesPaths.add(path);
return;
}
if(!f.isDirectory())
return;
final String[] childrenPaths=f.list();
for(final String fileName : childrenPaths)
{
if(fileName.startsWith("."))
continue;
f=new File(path+File.separator+fileName);
final String fullFilePath=f.getAbsolutePath();
if(f.isFile())
{
BitmapFactory.decodeFile(fullFilePath,options);
if(options.outHeight>=0&&options.outWidth>=0)
filesPaths.add(fullFilePath);
continue;
}
getPicturesPaths(fullFilePath,filesPaths);
}
}
}