Problem with generating pixel representation of image upload in Adobe XD


#1

Hey guys,

im currently developing a plugin for Adobe XD.

At some point the extension will access an image uploaded, and convert it to a pixel representation for further processing.

For this code out of the npm package get-image-pixel is used, shown below:

/**************************** Code Block *******************************/ module.exports = function(image, opts) {

opts = opts||{}

opts.x = opts.x||0

opts.y = opts.y||0

opts.width = typeof opts.width === ‘number’ ? opts.width : image.width

opts.height = typeof opts.height === ‘number’ ? opts.height : image.height

if (!context) {

canvas = document.createElement(“canvas”)

–> context = canvas.getContext(‘2d’)

}

canvas.width = opts.width

canvas.height = opts.height

context.clearRect(0,0,opts.width,opts.height)

context.drawImage(image, opts.x, opts.y, opts.width, opts.height, 0, 0, opts.width, opts.height)

var imgData

try {

imgData = context.getImageData(0, 0, opts.width, opts.height)

} catch(e){

module.exports.dispose()

throw e

}

return imgData.data

}

/************************* Code Block ****************************/

The problem i’m facing now is when trying to get the context of the created canvas (indicated by the little arrow in the Code Block).

The thrown problem is:

Plugin TypeError: canvas.getContext is not a function

Interestingly enough the created canvas is a owner document of the following form rather than a canvas element:

My guess is that it has something to do with the adobe xd environment and the creating of the canvas element is not working as

it would in a browser.

My guess is that it has something to do the t

{ _ownerDocument:

{ _ownerDocument: [Circular],

 _selectorEngine: 

  { _document: [Circular],

    _styleSheetList: {},

    _styleNodes: {},

    _styleSheets: [],

    _styleNodesMutation: 0,

    _linkNodesMutation: 0,

    _cachedNodeList: null,

    _cachedEnclosingClassNames: {}, 

Do you have any idea how to solve this problem or even another way to get the pixel representation of an image? You would really help me out!


#2

The XD environment doesn’t support all of the features of a browser.

There is a feature request for adding a BitmapData object here.

I can’t seem to find it now but there is somewhere some examples of loading a remote image, saving it locally and then reading it as a byte array.


#3

@Stavros
This tutorial might help.
https://adobexdplatform.com/plugin-docs/tutorials/how-to-make-network-requests/


#4

Thanks for your response! Although this sounds like something that could work, performing the image conversion into a byte array somewhere else then sending it to the user, I would prefer to do it locally on the XD instance of the user.
Maybe the support of some browser features would make it easier for plugin development.
Are you guys at Adobe thinking about that ? :slight_smile:


#6

If I’m understanding correctly, you have an image file which your plugin has downloaded from a server, and you want to bring that image into the user’s XD document? In that case, there’s no need to deal with its raw pixel data or to do any kind of image drawing yourself. Just save the image file to a temp folder and then create an ImageFill based on that file (assuming it’s a format XD supports, like PNG or JPG).

After downloading the image file (using XHR or fetch()), you can follow the example at the top of the ImageFill documentation except use your downloaded file in place of the getFileForOpening() filepicker call shown in that example.


#7

No the image file was uploaded by the user already. When he has different images in his boar the plugin is able to access the one which was selected. For further analysis the plugin needs to convert the image to raw pixel data. No server is involved.
With the get-image.pixel package (https://www.npmjs.com/package/get-image-pixels) should be done.

The problem occurs when creating a canvas and trying to access its context.
Specifically at the line marked with a little error:
–> context = canvas.getContext(‘2d’)


#8

The error occurs specifically because the execution environment does not have 2D canvas support. It’s on our backlog, but I have no timeframe for implementation.

The only workaround currently is to parse the image into an ArrayBuffer manually (there are libraries out there that can do this), do the desired pixel manipulation, and then go from there. It’s not as fast, but is an option. (This is how plugins like Stark work.)


#9

https://adobexdplatform.com/plugin-docs/tutorials/how-to-make-network-requests/ now reflects the modified ImageFill API. The example now saves the binary file and loads the file directly.