0

I need to convert a PNG file to Base64 data so that I can add it to a JSON object, using JXA (JavaScript Application Scripting).

JXA is limited compared to regular JavaScript so I can't immediately use functions from FileReader, etc.

From what I've read, there is no way that I know how to do this without using Objective-C/Cocoa (which I only started reading about today for this task).

I found the following code in another post:

NSArray *keys = [NSArray arrayWithObject:@"NSImageCompressionFactor"];
NSArray *objects = [NSArray arrayWithObject:@"1.0"];
NSDictionary *dictionary = [NSDictionary dictionaryWithObjects:objects forKeys:keys];

NSImage *image = [[NSImage alloc] initWithContentsOfFile:[imageField stringValue]];
NSBitmapImageRep *imageRep = [[NSBitmapImageRep alloc] initWithData:[image TIFFRepresentation]];
NSData *tiff_data = [imageRep representationUsingType:NSPNGFileType properties:dictionary];

NSString *base64 = [tiff_data encodeBase64WithNewlines:NO];

I believe it is pertinent to what I am trying to do- does anybody know how I can bridge this method to use it in JXA?

I have been reading over the JXA Cookbook's section on Syntax for calling ObjC functions, but I am having difficulty understanding it... this is all that I have come up with so far:

var desktopString = app.pathTo("desktop").toString()
var file = `${desktopString}/test.png`

ObjC.import("Cocoa");
var image = $.NSImage.alloc.initWithContentsOfFile(file)
var imageRep = $.NSBitmapImageRep.alloc.initWithData(image)

But I don't know how to proceed- I am thrown off by:

  • The whole initial NSArray/NSDictionary part
  • TIFFRepresentation (Do I need it? Where do I put it?)
  • NSData *tiff_data = [imageRep representationUsingType:NSPNGFileType properties:dictionary]; (There's no alloc! Why is dictionary needed?)
  • NSString *base64 = [tiff_data encodeBase64WithNewlines:NO]; (Again, no alloc.)

I would be very appreciative if somebody could point me in the right direction / give me a few pointers on how I can accomplish what I am trying to do.

Thank you in advance!

PE B
  • 65
  • 4

1 Answers1

0

Converting an image file into an NSImage representation and then onto a base-64 string is a lot of work, and was only applicable to the answer you sourced because the OP there was coming from a starting point of having NSImage class data. As you stated that you have a .png file, the route is much simpler:

ObjC.import('Foundation');


function fileToBase64(filepath) {
    const standardizedPath = $.NSString.stringWithString(filepath)
                                       .stringByStandardizingPath;
    const base64String = $.NSData.dataWithContentsOfFile(standardizedPath)
                                 .base64EncodedStringWithOptions(0);

    return ObjC.unwrap(base64String);
}


(() => {
    return fileToBase64('~/Desktop/test.png');
})();

For reference, this returns identical output to the following bash shell command:

base64 --input ~/Desktop/test.png

PS. For the benefit of learning, despite what the JXA Cookbook teaches, try not to import the entire Cocoa framework into your scripts, and just import the ones specific to the objective-c classes you're using.

CJK
  • 5,732
  • 1
  • 8
  • 26