本文介绍了使用NDK本地内存恢复图像返回黑色图像的无显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图恢复从本机内存(使用NDK,C / C ++)的图像,但它返回了我一个黑色的图像。

I am trying to restore the image from Native memory (using NDK,C/C++) but that returns me an Black Image.

我在做什么::

  • 1)从绘制对象获得的图像
  • 2)的旋转应用于图像
  • 3)旋转后应用灰度效果的图片
  • 4)最后我想保存的灰度图像中的SD卡

  • 1)get the image from Drawable
  • 2)apply the rotation to the image
  • 3)After rotation apply the grayscale effect to the image
  • 4)At the end i am trying to save the grayscale image in SD Card

对于所有上述步骤,我指的的真棒lib中,其中有本地方法来存储并恢复图像。

For all the above steps, i am referring this awesome lib,which have the native method to store and restore the images.

请注意图像被存储在SD卡,但是当我试图看到的图像,其全黑,没有显示在所有。

Please note image is being stored in the SD card but when i am trying to see the image,its totally black with no display at all.

我的Java实现::

public boolean onOptionsItemSelected(MenuItem item)
{
        switch (item.getItemId())
        {
        case R.id.item_rotate_90:
            options.inPreferredConfig = Config.ARGB_8888;
            bitmapOrig = BitmapFactory.decodeResource(this.getResources(), R.drawable.sample_cam,options);
            storeBitmap(bitmapOrig);
            bitmapOrig.recycle();
            rotateBitmap(90,_handler);
            tempBmp=getBitmapAndFree();

            bitmapWip = Bitmap.createBitmap(bitmapOrig.getWidth(),bitmapOrig.getHeight(),Config.ALPHA_8);
            jniConvertToGray(tempBmp,bitmapWip);

            if(bitmapWip!=null)
            {
                try
                {
                    Bitmap b = Bitmap.createBitmap(bitmapWip.getWidth(),bitmapWip.getHeight(),Bitmap.Config.ARGB_8888);
                    Canvas c = new Canvas(b);
                    Paint paint = new Paint();
                    ColorMatrix cm = new ColorMatrix();
                    ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
                    paint.setColorFilter(f);
                    c.drawBitmap(bitmapWip, 0, 0, paint);

                    storeBitmap(b);
                    SaveGrayScaledImage(b);
                    b.recycle();
                    tempBmp.recycle();

                } catch (IOException e) {
                    e.printStackTrace();
                }
                ivDisplay.setImageBitmap(bitmapWip);
            }
            break;
        }
}

我有没有让使用同样的方法, LIB在本地方法的任何变化(手段存储和恢复的图像)。

I have not make any changes in native method(means using the same method as this lib have for storing and restoring the image).

保存图片到SD卡::

private void SaveGrayScaledImage(Bitmap finalBitmap)throws IOException
{
        String imageFileName = "Temp" + "_gray";
        File albumF = new File("/mnt/sdcard/","gray_img");
        if(!albumF.exists())
        {
            albumF.mkdirs();
        }
        // File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX,
        // albumF);
        File imageF = new File(albumF,imageFileName + ".jpeg");

        if (imageF.exists()) {
            imageF.delete();
            imageF.createNewFile();
        }
        try {
            FileOutputStream out = new FileOutputStream(imageF);
            finalBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            imageF = null;
        }
}

在谷歌上搜索,我发现,(可能是我错了)的图像,返回本机内存已在ALPHA_8位图的配置,所以我转换配置ALPHA_8 T0 ARGB_8888,但结果是一样的。

While googling, i found that(may be i am wrong) image which returns for Native Memory have the ALPHA_8 bitmap config,so i convert the config ALPHA_8 t0 ARGB_8888,but the result is same.

从ALPHA_8位图转换为ARGB_8888 ::

Bitmap b = Bitmap.createBitmap(bitmapWip.getWidth(),bitmapWip.getHeight(),Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
Paint paint = new Paint();
ColorMatrix cm = new ColorMatrix();
ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
paint.setColorFilter(f);
c.drawBitmap(bitmapWip, 0, 0, paint);

StoreBimap funcation ::

public void storeBitmap(final Bitmap bitmap)
{
    if(_handler!=null)
        freeBitmap();
    _handler=jniStoreBitmapData(bitmap);
}

我不知道在哪里我错了。我检查的lib方法和implmentation一次又一次地找到问题。

I have no clue about where i was wrong. i have checked the lib methods and implmentation again and again to find the issue.

我已经花了我很多时间在这个小问题,它真的令人沮丧的我。让我知道,请,如果你需要任何东西从我的身边。请帮我解决这个问题。

I have spent my many hours on this small issue and it really frustrating me.Let me know please if you need anything else from my side.Please help me to resolve this issue.

在提前非常感谢......

Many Thanks in Advance....

修改::

bitmapHolder=new JniBitmapHolder();
    final Options options=new Options();
    BitmapFactory.decodeFile(picPath, options);
    options.inJustDecodeBounds=true;
             options.inPreferredConfig=Config.ARGB_8888;
             prepareForDownsampling(options,192,256);
             System.gc();
             bmpGrayscale=BitmapFactory.decodeFile(picPath,options);
             int width = bmpGrayscale.getWidth();
             int height = bmpGrayscale.getHeight();
             bitmapHolder.storeBitmap(bmpGrayscale);
             bmpGrayscale.recycle();


   Bitmap thumbnail = null;
   int rotationInDegrees = 0;
   if (picPath != null) {
    Uri uri = Uri.parse(picPath);
    ExifInterface exif = null;
    try {
     exif = new ExifInterface(uri.getPath());
    } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
    }

    int rotation = exif.getAttributeInt(
      ExifInterface.TAG_ORIENTATION,
      ExifInterface.ORIENTATION_NORMAL);

    rotationInDegrees = exifToDegrees(rotation);
   }

   rotationInDegrees = 90;


    ByteBuffer _handler =null;
    switch(rotationInDegrees)
               {
               case 90:
                 bitmapHolder.rotateBitmapCw90();
                 break;
               case 180:
                 bitmapHolder.rotateBitmap180();
                 break;

               }



    Bitmap bitmapWip = Bitmap.createBitmap(width,height,Config.ALPHA_8);
    bitmapHolder.bitmapGrayScale(bitmapWip);

     if(bitmapWip!=null){
      File CurrentFile = saveGrayScaledIamge(bitmapWip,
        takePhotoFile);
     }

我按照你的建议/步骤,但结果是一样的,让黑色图像无显示。

I have followed your suggestion/steps but the result is same,getting black image with no display.

推荐答案

好,我找到了多个问题和技巧的改进:

ok I've found multiple problems and tips for improvements:

  • 第一createBitmap运行与宽*高上得到了旋转,而不是高*宽位图。这应该是因为:

  • the first createBitmap is run with width*height on a bitmap that got rotated instead of height*width. this should be as:

rotateBitmap(90,_handler);
tempBmp=getBitmapAndFree();
bitmapWip=Bitmap.createBitmap(bitmapOrig.getHeight(),bitmapOrig.getWidth(),Config.ALPHA_8);

  • 保存文件的时候你没有得到正确的路径(使用硬codeD路径,林特警告说这件事)。

  • when saving file you don't get the correct path (you use a hardcoded path, and Lint warns about it).

    jniConvertToGray并不真正需要走了过来阵列,可以只使用一个指针,因为它只是运行在单个像素。您存储的位图到JNI,而不是一次两次(只是做:商店,旋转,灰度,恢复和放大器;免费)。

    jniConvertToGray doesn't really need to go over arrays and can just use a pointer, as it just runs on a single pixel. you store the bitmap into JNI twice instead of once (just do: store, rotate, grayscale, restore&free).

    您已经处理完之后不使用新的位图,所以如果我叫旋转多次,它似乎并没有做任何事情。

    you don't use the new bitmap after you have finished working on it, so if I call rotation multiple times, it doesn't seem to do anything.

    您已经拥有bitmapWip旋转和grayscaled。为什么你需要一个新的位图,有它在它的内容,做一个灰度就可以了,然后将其保存?

    you already have bitmapWip rotated and grayscaled. why do you need to make a new bitmap that has its content in it, do a grayscale on it, and then save it ?

    函数应该被命名为在其名称的开头小写字母。

    functions should be named with lowercase letter in the beginning of their names.

    最后,最重要的事情:你用ALPHA_8为您展示和需要保存到文件的图像。这个配置没有颜色。这是一个面具。为了看到这个问题,您应该设置背景颜色的ImageView的:

    and finally , the most important thing: you use ALPHA_8 for the image that you show and need to save to file. this configuration has no color. it's a mask. In order to see the problem, you should set a background color to the imageView :

    ivDisplay.setBackgroundColor(0xFFff0000);
    

    选择旋转前,你什么也看不到红色。选择它后,你认为是白色的一切,实际上已经变成红色。这是因为它是透明的......

    before choosing the rotation, you see nothing red. after choosing it, everything you think is white, has actually become red. that's because it's transparent...

    如果你发展的任何阶段,您已经成功保存图像文件,并认为这是一个黑色的图像(但大小不为0),尝试对其进行编辑,并把背景后面。也许你很幸运,只是得到了透明像素...

    If in any phase of your development you've succeeded saving the image to a file and thought it's a black image (yet the size is not 0) , try to edit it and put a background behind it. Maybe you got lucky and just got transparent pixels...

    添加你把文件保存为JPG格式,不支持透明度,也可能有助于意外行为的事实。

    Adding the fact that you save the file to a jpg format, which doesn't support transparency, might also contribute to unexpected behaviors.

    为了解决这个问题,你应该使用相同的技术我用 - 用一个位图所有的时间。无需创建这么多。只应该存在于Java的世界,它应该支持有颜色的。

    in order to solve this, you should use the same technique i've used - use a single bitmap all the time. no need to create so many. only one should exist on the java world, and it should support having colors.

    这篇关于使用NDK本地内存恢复图像返回黑色图像的无显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

  • 09-02 13:46