Jnibitmapoperations Rotation Causes Image Corruption
i'm developing an app i which users can upload images from the camera to an event, i did it in the usual way, but when i got to the part of rotating it according to the Exif interf
Solution 1:
ok, the bug was with setting the wrong width and height for the rotation functions.
i've now updated the code. now it should work.
I am very sorry for this bug. was sure that i've fixed it before. i've now added the ability to also rotate by 180 degrees, so that you won't need to rotate twice (a little more efficient).
and just to say that the sample code wasn't for nothing, here's a nicer sample code.
it will go over all of your camera images, and rotate them in any of the 3 ways, and put the result files into Android/data/PACKAGE_NAME .
here's the code:
publicclassMainActivityextendsActivity
{
@OverrideprotectedvoidonCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final File picFolder=Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
finalint screenWidth=getResources().getDisplayMetrics().widthPixels;
finalint screenHeight=getResources().getDisplayMetrics().heightPixels;
final File outputDir=getExternalFilesDir(null);
final ProgressDialog progressDialog=ProgressDialog.show(this,"please wait","processing");
newAsyncTask<Void,Void,Void>()
{
@Overrideprotected Void doInBackground(final Void... params)
{
final File[] listFiles=outputDir.listFiles((FileFilter)null);
for(final File file : listFiles)
file.delete();
final List<String> imageFilesPaths=newArrayList<String>();
getPicturesPaths(picFolder.getAbsolutePath(),imageFilesPaths);
final JniBitmapHolder bitmapHolder=newJniBitmapHolder();
int i=0;
final Options options=newOptions();
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)
{
case0:
bitmapHolder.rotateBitmapCw90();
break;
case1:
bitmapHolder.rotateBitmap180();
break;
case2:
bitmapHolder.rotateBitmapCcw90();
break;
}
b=bitmapHolder.getBitmapAndFree();
final File imageFile=newFile(outputDir.getAbsoluteFile()+File.separator+System.currentTimeMillis()+".jpg");
imageFile.getParentFile().mkdirs();
FileOutputStream stream=null;
try
{
stream=newFileOutputStream(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();
}
}
}
returnnull;
}
@OverrideprotectedvoidonPostExecute(final Void result)
{
super.onPostExecute(result);
progressDialog.dismiss();
finish();
}
}.execute();
}
privatestaticvoidprepareForDownsampling(final Options bitmapOptions,finalint reqWidth,finalint reqHeight)
{
finalint 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;
}
}
publicstaticintcalculateInSampleSize(final BitmapFactory.Options options,finalint reqWidth,finalint reqHeight)
{
finalint height=options.outHeight;
finalint width=options.outWidth;
int inSampleSize=1;
if(height>reqHeight||width>reqWidth)
{
finalint heightRatio=Math.round((float)height/(float)reqHeight);
finalint widthRatio=Math.round((float)width/(float)reqWidth);
inSampleSize=heightRatio<widthRatio ? heightRatio : widthRatio;
}
return Math.max(inSampleSize,1);
}
privatestaticvoidgetPicturesPaths(final String path,final List<String> filesPaths)
{
final Options options=newOptions();
options.inJustDecodeBounds=true;
File f=newFile(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=newFile(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);
}
}
}
Post a Comment for "Jnibitmapoperations Rotation Causes Image Corruption"