Кодировать / декодировать PNG в строки base64 в JXA / JavaScript - PullRequest
2 голосов
/ 12 июня 2019

Я пытаюсь написать JXA-скрипт в Apple Script Editor, который преобразует PNG-файлы в строки base64, которые затем можно добавить в объект JSON.

Кажется, я не могу найти метод JXA, который подходит для выполнения кодирования / декодирования base64.

Я наткнулся на каплю , написанную с использованием Shell Script , которая передает задачу на openssl , а затем выводит файл .b64:

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

Так что я подумал о том, чтобы Франкенштейн разработал этот метод, который использует evalAS до , запускает встроенный 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 в сценарии, но все это выглядит довольно скучным и неуклюжим.

Я знаю, что можно использовать Какао в сценариях JXA , и я вижу, что существуют методы для кодирования / декодирования base64 в Какао ...

а также Objective-C :

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

Поваренная книга JXA содержит целый раздел, в котором Синтаксис для вызова функций ObjC , который я пытаюсь прочитать. Из того, что я понимаю, это должно выглядеть примерно так:

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.UIImagePNGR Представление не является функцией. (В '$ .NSData.alloc.UIImagePNGRepresentation (изображение)', «$ .NSData.alloc.UIImagePNGRepresentation» не определено)

Я предполагаю, что это потому, что UIImagePNGRepresentation относится к UIKit фреймворку, который является iOS, а не OS X?

Я наткнулся на этот пост , который предлагает это:

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. Я просто решил заставить что-то работать.

Я надеялся, что есть какой-то способ сделать это на простом старом JavaScript, который будет работать в сценарии JXA?

Я с нетерпением жду любых ответов и / или указателей, которые вы можете предоставить Спасибо всем заранее!

Ответы [ 2 ]

1 голос
/ 12 июня 2019

Извините, я никогда не работал с 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

1 голос
/ 12 июня 2019

Используйте код ниже. Считайте файл в файл var из элемента ввода файла jquery, используя FileReader в readDataAsURL. Тогда у вас будет 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>
...