• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Scripting tools to get the color of a particular dot placed placed on an image layer?

Engaged ,
Apr 15, 2023 Apr 15, 2023

Copy link to clipboard

Copied

Hi all.
Does Illustrator have scripting tools to get the color of a particular dot or 3x3 dot patch placed on an image layer?

 

There is an image in the layer, you need to find the color of a certain point of this image...

TOPICS
Scripting

Views

1.4K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Adobe
Guide ,
Apr 15, 2023 Apr 15, 2023

Copy link to clipboard

Copied

Is it a raster image?  How is the dot/patch to be targeted? 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Apr 16, 2023 Apr 16, 2023

Copy link to clipboard

Copied

in the document there are two layers in the first layer is a bitmap, in the second is a path element. You need to get the color value of the rasterized image, according to the location coordinates of the path element

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Apr 17, 2023 Apr 17, 2023

Copy link to clipboard

Copied

You really should add some more details to this otherwise it forces us to assume a lot of information, like:

  • How the BMP and path are each located or targeted. You say they're in separate layers, I don't know the names or order of these layers or how you intend to use them
  • The color profile and bit depth of the BMP, which I assumed was RGB and 32 instead of BMP, 16 or 24
  • Whether there are any other paths in this file that aren't the same as the one used for pixel analysis
  • Whether your dot will ever be outside the bounds of the image layer
  • Whether there will ever be multiple colors found in the path bounds or only a single one
  • What the script will actually do with this color once found

 

When you don't include details like this it means it takes a lot more work to help you, and if you want to get others to volunteer time and effort on your behalf then you'll find that not making it harder (intentionally or otherwise) for them to help will go a long way in determining whether or not you'll get many responses if not just questions prodding you to add more detail in the first place.

 

Anyway, there is no vanilla scripting API method to do this, but it's still possible given that BMP files are uncompressed pixel data. You have to manually parse the bytes of the BMP to recreate it's pixel data then you can narrow down the pixels to what was inside the bounds of the path relative to item, then narrow it further to the colors within:

 

(function () {
  if (!app.selection.length) {
    alert("Must select the path used for pixel analysis");
    return null;
  }
  Array.prototype.filter = function (callback) {
    var filtered = [];
    for (var i = 0; i < this.length; i++)
      if (callback(this[i], i, this)) filtered.push(this[i]);
    return filtered;
  };
  RGBColor.prototype.create = function (red, green, blue) {
    this.red = red;
    this.green = green;
    this.blue = blue;
    return this;
  };
  function parseBitmap(binaryData) {
    if (binaryData[0] !== 0x42 || binaryData[1] !== 0x4d) {
      alert("Invalid BMP format.");
      return null;
    }
    var pixelOffset =
        binaryData[10] +
        (binaryData[11] << 8) +
        (binaryData[12] << 16) +
        (binaryData[13] << 24),
      width =
        binaryData[18] +
        (binaryData[19] << 8) +
        (binaryData[20] << 16) +
        (binaryData[21] << 24),
      height =
        binaryData[22] +
        (binaryData[23] << 8) +
        (binaryData[24] << 16) +
        (binaryData[25] << 24),
      bitDepth = binaryData[28] + (binaryData[29] << 8),
      bytesPerPixel = bitDepth / 8,
      pixelData = new Array(width * height);
    for (var i = 0; i < pixelData.length; i++) {
      var offset = pixelOffset + i * bytesPerPixel;
      pixelData[i] = {
        r: binaryData[offset + 2],
        g: binaryData[offset + 1],
        b: binaryData[offset],
        a: binaryData[offset + 3],
        x: i % width,
        y: Math.floor(i / width),
      };
    }
    return pixelData;
  }

  function getBinaryFromFile(item) {
    var file = item.file;
    file.open("r");
    file.encoding = "BINARY";
    var data = [];
    while (!file.eof) data.push(file.readch().charCodeAt(0));
    file.close();
    return data;
  }

  function getCoordinateOffsetFromPlacedItem() {
    var haystack = app.activeDocument.placedItems[0].geometricBounds,
      needle = app.selection[0].geometricBounds;
    return {
      x: Math.abs(haystack[0] - needle[0]),
      y: Math.abs(haystack[1] - needle[1]),
      w: Math.abs(needle[2] - needle[0]),
      h: Math.abs(needle[3] - needle[1]),
    };
  }
  function retrieveRGBValuesFromBitmap() {
    var target = app.activeDocument.placedItems[0],
      bounds = getCoordinateOffsetFromPlacedItem();
    var binaryData = getBinaryFromFile(target);
    var parsed = parseBitmap(binaryData);
    var result = parsed.filter(function (pixel) {
      return (
        pixel.x >= bounds.x &&
        pixel.x <= bounds.x + bounds.w &&
        pixel.y >= bounds.y &&
        pixel.y <= bounds.y + bounds.h
      );
    });
    if (!result) {
      alert("Faulty result");
      return null;
    } else {
      // Not really sure what you want to do with this since it isn't stated, so make first result the active app color
      app.activeDocument.defaultFillColor = new RGBColor().create(
        result[0].r,
        result[0].g,
        result[0].b
      );
      var msg =
        "Script found RGB(" +
        result[0].r +
        "," +
        result[0].g +
        "," +
        result[0].b +
        ")";
      alert(msg);
      return null;
    }
  }
  try {
    retrieveRGBValuesFromBitmap();
  } catch (err) {
    alert(err);
  }
})();

 In the test file I'm using, the below square is a BMP image that contains 3 colors: black, red, and blue. The white stroke square is the pathItem in Illustrator I'm using to analyze the pixels of the BMP image and it accurately reads RGB(19,100,216) which is the color of the blue inside the BMP image and contained nowhere else in the active document:

ice_screenshot_20230417-215144.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Apr 17, 2023 Apr 17, 2023

Copy link to clipboard

Copied

Hi @Inventsable, this is awesome! I was thinking about something like this, but didn't understand what I was doing when it comes to the getting the bitmap binary data.

 

Here's an idea: export BMP of the doc (or artboard?) and read that, rather than an actual BMP link. That way, it doesn't matter what format the linked image is, and it's scale or rotation. Tell me if I've missed something. I would also recommend the user create a 1 x 1pixel square path item for their "guide" object.

 

Anyway, thanks heaps for sharing this approach—I'd never have got that right.

- Mark

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Apr 18, 2023 Apr 18, 2023

Copy link to clipboard

Copied

Thanks! Also great idea, I went ahead and rewrote it to be an agnostic library with that in mind. Now it'll do every pixel of a given canvas or be much more lightweight and given a single pixel if not a list of coordinates, plus several options and even some lifecycle hooks 👍

 

Instead of it being reliant on a guide or any specific path, I figure any user could relatively easily input the coordinates from a guide object to the arguments. This way it'd remain as flexible as possible and wouldn't be useful solely for this one use case and file structure.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Apr 18, 2023 Apr 18, 2023

Copy link to clipboard

Copied

Hi @Inventsable

Thank you for your response.


I'm not very familiar with Abobe JavaScript, and English is not my native language, so I have difficulty communicating, especially on such complex topics.
When working with Abobe JavaScrip, comes the understanding that besides it, you still need to know about some JavaScrip language constructs. So please forgive me for the incomplete description of the question of interest to me.


The purpose of such a script is to paint the overlying path with the color of the bitmap below it. The target is the center of the bounding path frames, as indicated in your example.

 

By bitmap, I mean a picture in JPG format. Will your code work with JPG format?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Apr 18, 2023 Apr 18, 2023

Copy link to clipboard

Copied

The current version of the script wouldn't work with any format that isn't BMP, but Mark's idea to export the entire document as BMP and use that would solve this and make it work for JPG as well. I won't have time to update it until after work today though, so it'll be a while before I give an updated reply.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Apr 18, 2023 Apr 18, 2023

Copy link to clipboard

Copied

Example.png

Thank you for your response.

 

The picture shows the conditions under which I run your code for execution.
The linked image is in BMP format with color depth 16.
Program freezes when executing code

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Apr 18, 2023 Apr 18, 2023

Copy link to clipboard

Copied

Thanks. The current script works at 32 bit depth and would fail on 16 since the bits need to be parsed differently at that depth. I'll update it later tonight in a way that solves for any depth (or at least exports at 32 and parses from there).

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Apr 18, 2023 Apr 18, 2023

Copy link to clipboard

Copied

I did work on this and mostly finished, though I haven't applied it to your exact file yet. It'd be as easy as using #include with the script then targeting your bottom right pixel of the pathItem though, if you're keen to try yourself.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Apr 18, 2023 Apr 18, 2023

Copy link to clipboard

Copied

Thank you for your response.

I'm trying to transfer position data to Photoshop, get the color value there and transfer this data back to Illustrator using the bridge function. It will be necessary to do such an operation for many points ... I wonder what will be faster. Let's try your version .. Special thanks for the work you have done....

 
 
 
 
 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Apr 19, 2023 Apr 19, 2023

Copy link to clipboard

Copied

brevity is the sister of genius...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Apr 19, 2023 Apr 19, 2023

Copy link to clipboard

Copied

LATEST

Github.com.... has a question...

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines