在JXA / JavaScript中将PNG编码/解码为base64字符串

时间:2019-06-12 05:05:18

标签: javascript cocoa base64 applescript javascript-automation

我试图在Apple脚本编辑器中编写一个JXA脚本,该脚本将PNG文件转换为base64字符串,然后可以将其添加到JSON对象中。

我似乎找不到能够执行base64编码/解码部分的JXA方法。

我遇到了一个droplet which was written using Shell Script,该任务将任务外包给 openssl ,然后输出一个.b64文件:

for f in "$@"
do
    openssl base64 -in "$f" -out "$f.b64"
done

因此,我想到了科学怪人将其扩展为使用 evalAS run inline AppleScript的方法,例如:

(() => {
    'use strict';

    // evalAS2 :: String -> IO a
    const evalAS2 = s => {
        const a = Application.currentApplication();
        return (a.includeStandardAdditions = true, a)
            .runScript(s);
    };

    return evalAS2(
        'use scripting additions\n\
         for f in' + '\x22' + file + '\x22\n'
         do
         openssl base64 -in "$f" -out "$f.b64"
         done'
    );
})();

然后在脚本中重新打开.b64文件,但是这一切似乎很漫长且笨拙。

我知道可以使用Cocoa in JXA scripts,并且我发现有base64 encoding/decoding in Cocoa ...的方法...

以及Objective-C

NSData *imageData = UIImagePNGRepresentation(myImageView.image);
NSString * base64String = [imageData base64EncodedStringWithOptions:0];

JXA Cookbook的整个章节都覆盖了Syntax for Calling ObjC functions,我正在尝试阅读。 据我了解,它看起来应该像这样:

var image_to_convert = $.NSData.alloc.UIImagePNGRepresentation(image)
var image_as_base64 = $.NSString.alloc.base64EncodedStringWithOptions(image_to_convert) 

但是我对此完全不了解,所以我仍然很难理解所有内容。

在上面的推测性代码中,我不确定从何处获取 image 数据?

我正在尝试:

ObjC.import("Cocoa");
var image = $.NSImage.alloc.initWithContentsOfFile(file)
console.log(image);
var image_to_convert = $.NSData.alloc.UIImagePNGRepresentation(image)
var image_as_base64 = $.NSString.alloc.base64EncodedStringWithOptions(image_to_convert)

但这会导致以下错误:

  

$。NSData.alloc.UIImagePNGRepresentation不是一个函数。 (在   '$ .NSData.alloc.UIImagePNGRepresentation(image)',   '$ .NSData.alloc.UIImagePNGRepresentation'未定义)

我猜这是因为UIImagePNGRepresentation UIKit 框架的东西,这是iOS而不是OS X?

我碰到了this 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];

但是,再次,我不知道这如何转换为JXA。我只是下定决心要工作。

我希望有某种方法可以在可以在JXA脚本中使用的普通旧JavaScript中做到这一点?

我期待您可能提供的所有答案和/或指示。预先谢谢大家!

2 个答案:

答案 0 :(得分:1)

使用以下代码。使用“ readDataAsURL”中的FileReader将文件从jquery文件输入元素读取为var文件。然后,您将把png作为base64格式的字符串。

您可能需要用','分隔base64字符串,以获取字符串的实际数据部分,您可以将其包含在JSON中并通过API发送到后端。

var file = $('#fileUpload').prop('files')[0];
var base64data;
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function() {
  base64data = reader.result;
  var dataUrl = base64data.split(",");
};

通常,您将获得的base64字符串采用这种形式。

'data:image/png;base64,STREAM_OF_SOME_CHARACTERS...

因此STREAM_OF_SOME_CHARACTERS ...(dataUrl)是实际图像数据所在的位置。

此外,您可以通过以下方式在HTML页面中打开图像

<img src=base64data>

答案 1 :(得分:1)

对不起,我从未使用过JXA,但是在Objective-C中工作很多。

我认为您遇到了编译错误,因为您试图始终分配新的对象。

我认为这应该是简单的:

ObjC.import("Cocoa");
var imageData = $.NSData.alloc.initWithContentsOfFile(file);
console.log(imageData);
var image_as_base64 = imageData.base64EncodedStringWithOptions(0); // Call method of allocated object

0是Base64编码的常数,仅用于获取base64字符串。

edit:
var theString = ObjC.unwrap(image_as_base64);

这使值对JXA可见