javaandroidimagepdfapportable

PDF page to Image, Apportable BridgeKit


I modified some code from this post:

Need help to convert a Pdf page into Bitmap in Android Java

To try and get a page from the pdf, convert it to a byte[] and pass it back to a Xcode project to be displayed. I'm doing this using Apportables BridgeKit framework and it compiles without any errors.

The problem is that the app crashes once loaded on to the device.

ImageExtractor.java

package com.pdflib;

import android.graphics.Bitmap;
import android.os.Environment;
import android.util.Log;

import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;

import net.sf.andpdf.nio.ByteBuffer;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.RandomAccessFile;

public class ImageExtractor
{
    //Globals:
    private int ViewSize = 0;

    //Load Images:
    private byte[] pdfLoadImages()
    {
        try
        {
            File file = new File(Environment.getExternalStorageDirectory().getPath() + "/backs.pdf");
            RandomAccessFile f = new RandomAccessFile(file, "r");
            byte[] data = new byte[(int)f.length()];
            f.readFully(data);

            //create pdf document object from bytes
            ByteBuffer bb = ByteBuffer.NEW(data);
            PDFFile pdf = new PDFFile(bb);
            //Get the first page from the pdf doc
            PDFPage PDFpage = pdf.getPage(1, true);
            //create a scaling value according to the WebView Width
            final float scale = ViewSize / PDFpage.getWidth() * 0.95f;
            //convert the page into a bitmap with a scaling value
            Bitmap page = PDFpage.getImage((int)(PDFpage.getWidth() * scale), (int)(PDFpage.getHeight() * scale), null, true, true);
            //save the bitmap to a byte array
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            page.compress(Bitmap.CompressFormat.PNG, 100, stream);
            byte[] byteArray = stream.toByteArray();
            stream.reset();

            return byteArray;
        }
        catch (Exception e)
        {
            Log.d("error", e.toString());
        }

        return null;
    }
}

MainScene.m

#import "MainScene.h"
#import "CreateTexture.h"

@implementation MainScene

- (void)didLoadFromCCB
{
    CGSize size = CGSizeMake(100, 75);

    CreateTexture* sprite = [[CreateTexture alloc] initWithBackSize: size];

    sprite.positionInPoints = CGPointMake(100, 100);

    [self addChild: sprite];
}

@end

CreateTexture.m

#import "CreateTexture.h"

#ifdef ANDROID
#import "PDFBridge.h"
#endif

@implementation CreateTexture

- (instancetype) initWithBackSize: (CGSize) size
{
    #ifdef APPORTABLE
        PDFBridge *temp = [[PDFBridge alloc] init];
        [temp TestBridge];
        NSData* tempBytes = temp.imageBytes;

        UIImage* image = [[UIImage alloc] initWithData:tempBytes];

        CCTexture* texture = [[CCTexture alloc] initWithCGImage: image.CGImage contentScale: image.scale];

        self = [super initWithTexture: texture];

    #endif

    NSAssert (self, @"Initializer failed");

    return self;
}

@end

PDFBridge.m

#import "PDFBridge.h"

@implementation PDFBridge

@dynamic imageBytes;

- (void) TestBridge
{
    #ifdef APPORTABLE
    [PDFBridge registerInstanceMethod:@"pdfLoadImages"
                             selector:@selector(imageBytes)
                            returnValue:[NSData className]];
    #endif
}

+ (NSString *)className
{
    return @"com.pdflib.ImageExtractor";
}

@end

Solution

  • Instead of a - (void) TestBridge method, you should override +[JavaObject initializeJava], so something like:

    + (void)initializeJava
    {
        // always call [super initializeJava]
        [super initializeJava];
    
        // register bridge constructors, methods, callbacks here ...
    }
    

    Also note the open-source ParseBridge provides a fairly extensive example of using Apportable BridgeKit.