0

I'm currently trying to save a bitmap using the NDK without restoring the Java Object but using directly a C++ pixel array.

I have already the bitmap stored in a JniBitmapHolder and I can successfully get the stored pixels. I would like to try to save them without call the Bitmap.create method.

Currently I'm trying to do it like this (without success):

Util.saveImageSync(Util.getOutputMediaFile("filtered"), jniBitmap.getBitmapArray());

And the method is implemented like this:

public static void saveImageSync(final File outputFile, final ByteBuffer buffer){
    FileOutputStream out = null;
    try {
        out = new FileOutputStream(outputFile);
        out.getChannel().write(buffer);
    } catch (Exception e) {
        Dbg.d("ERROR", e);
    } finally {
        try {
            if (out != null) {
                out.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I've added the method getBitmaArray to the library, like this:

JNIEXPORT jobject JNICALL Java_com_jni_bitmap_1operations_JniBitmapHolder_jniGetBitmapArray(
    JNIEnv * env, jobject obj, jobject handle) {
JniBitmap *jniBitmap = (JniBitmap *) env->GetDirectBufferAddress(handle);
jniBitmap->_storedBitmapPixels;
return env->NewDirectByteBuffer(jniBitmap->_storedBitmapPixels, 0);

}

But it seems that the direct pixel array isn't enough or correct. Any other idea to save pixels directly to file without the need of creating the Java Bitmap?

Also hints/pointers are really appreciated.

Filnik
  • 352
  • 1
  • 12
  • 33

2 Answers2

0

Yes, you need to write bitmap header to create a compliant file. See Writing BMP image in pure c/c++ without other libraries for explanation how this can be done from native code.

Community
  • 1
  • 1
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • Question, does it work even if I want it to be saved like a .jpg (the original file is a .jpg indeed) and not a .bmp file? Thank you anyway for the answer :) – Filnik Sep 15 '15 at 08:04
  • I don't understand your use case. If you have a JPEG and want to write it to file, why do you need a bitmap between? – Alex Cohn Sep 15 '15 at 16:35
  • with bitmap I mean the Android's Bitmap class. I've downloaded 2 JPEGs from the net using Universal Image Loader and it returns a Bitmap object. Then I have created a modified version of the pixels, but I don't want to create a new Bitmap object just to return it to the java and save it.. I would like to save it directly. Yes, it's a bitmap but of a JPEG file. Sorry If I'm not that clear :) – Filnik Sep 16 '15 at 08:26
  • If you modified some pixels, then the fact that it originally comes from JPEG will no help. You can compress a bitmap into JPEG in native without going through Java. Have a look at *[libjpeg-turbo](http://stackoverflow.com/questions/24548952/android-how-to-use-libjpeg-turbo-library)* – Alex Cohn Sep 16 '15 at 08:34
0

After some further investigation, the fastest way was to keep a support Bitmap, pass that to the C++ without creating a new bitmap every time I use that function, and just use it to use directly the Java method to save the pixels.

Thanks though to Alex for the answer :) actually the problem was the missing headers.

Filnik
  • 352
  • 1
  • 12
  • 33