JniBitmapOperations旋转引起的图像损坏 [英] JniBitmapOperations rotation causes image corruption

查看:141
本文介绍了JniBitmapOperations旋转引起的图像损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发一个应用程序,我哪些用户可以从相机将图像上传到一个事件,我做到了用通常的方法,但是当我根据Exif的界面我有时会得到OOM旋转它的一部分错误,这是很无奈的,我决定尝试使用 JniBitmapOperations库
这似乎做工精细(我不会OOM错误),但是当试图旋转它得到腐败的形象和搞砸了:/继承人图片

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 interface i would sometimes get OOM errors, which were really frustrating, i decided to try and use JniBitmapOperations library which seemed to work fine (i wouldn't get OOM errors) but when trying to rotate the image it gets corrupt and messed up :/ heres pictures

你可以看到上面的图片旋转到正确的位置,但所有的腐败
下面的一个是原始

as you can see the picture above is rotated to the correct position but is all corrupt the one below is the original

这里是code的一部分是相关的:

here is the part of the code that is relevant:

        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();
            }
        }
    }

我将AP preciate任何帮助!

i would appreciate any help!

推荐答案

确定,错误与设置错误的宽度和高度旋转的功能。

ok, the bug was with setting the wrong width and height for the rotation functions.

我现在已经更新了code。现在它应该工作。

i've now updated the code. now it should work.

我对这个错误很遗憾。确信,我以前固定它。现在我已经加入也180度旋转,这样你就不会需要转动两次(一点点更有效)的能力。

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).

和刚说,样本code是不是没有,这里有一个更好的样本code。

and just to say that the sample code wasn't for nothing, here's a nicer sample code.

它会在您所有的摄像机图像,并在任何的3种方式旋转它们,然后把结果放到文件转换成Android的/数据/ PACKAGE_NAME。

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 .

这里的code:

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

这篇关于JniBitmapOperations旋转引起的图像损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆