Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scripting API: New image format? #2695

Open
Phlosioneer opened this issue Dec 12, 2019 · 7 comments
Open

Scripting API: New image format? #2695

Phlosioneer opened this issue Dec 12, 2019 · 7 comments
Labels
feature It's a feature, not a bug.

Comments

@Phlosioneer
Copy link
Contributor

Hey, I'm trying to use the new scripting API to allow tiled to read a new image format for tilesets. However, the API only allows registering handlers for Tileset files and TileMap files.

I'd like to suggest this as a workable API:

tiled.registerImageFormat(shortName: string, imageFormat: object): void

The `imageFormat` object is expected to have the following properties:
- name: String
    Name of the format as shown in the file dialog
- extension: String
    File extension used by the format
- read: function(fileName: string): Image
    A function that reads an image from the given file. Can use TextFile or BinaryFile to read the file.
- hasChanged: function(fileName: string, timeOfLastRead: date): bool
    A function that is called periodically to check if the image has updated. This function should be as fast as possible. timeOfLastRead is the timestamp when `read` was last called.
@bjorn bjorn added the feature It's a feature, not a bug. label Dec 12, 2019
@bjorn
Copy link
Member

bjorn commented Dec 12, 2019

What image format are you looking to support? Qt only supports adding custom image formats through C++ plugins and I don't think it even supports even a C++ API to register custom formats. If this is about adding support for a common image format then maybe we could ship another image format plugin.

Alternatively, we could of course route all image loading through a custom function that also takes registered formats from JavaScript into account.

Why the custom hasChanged check? As long as the image is simply a file on disk, Tiled already watches it for changes (if it's a tileset image, because individual tile images and image layer images are not yet watched for changes...).

@Phlosioneer
Copy link
Contributor Author

I'm trying to use a generated image as a tileset image. That generated image has two input files. So the normal "watch the file" approach that's built in wouldn't work.

Currently I have to remember to update it whenever either file changes, and I have to perform the generation in a particular order. It's error prone.

@Phlosioneer
Copy link
Contributor Author

As for the image format, in this case I'm just going to make a temporary png file and load that, after running the generator (if needed). So QT doesn't have to bend over backwards for the format, I just need to be able to intercept reads and override the auto-checking behavior.

The exact process in my case is that I'm taking a .ase file, exporting it to PNG, and then running a postprocessing script afterwards. If the script or the ase file change, I want the output to update accordingly.

@Phlosioneer
Copy link
Contributor Author

In the more general case, could we allow a script to generate BMP-formatted image data and then "trick" qt into thinking that it's a bmp file?

@bjorn
Copy link
Member

bjorn commented Dec 15, 2019

Currently I have to remember to update it whenever either file changes, and I have to perform the generation in a particular order. It's error prone.

I think the best way to support this case would be to expose the FileSystemWatcher class in the script API and give the script a way to trigger a reload.

In the more general case, could we allow a script to generate BMP-formatted image data and then "trick" qt into thinking that it's a bmp file?

We can definitely also expose a script function to turn a byte array into an image with any supported format. Essentially exposing QImage::fromData.

@samhocevar
Copy link
Contributor

@bjorn exposing QImage::fromData would be great, yes. Right now there is no equivalent to the Python way of doing Tileset.data().loadFromImage().

bjorn added a commit that referenced this issue Apr 22, 2020
Now a script can create an image, either directly or by loading from a
file or data or based on raw data. Then, the image can be passed to
Tileset.loadFromImage or Tile.setImage.

Related to issue #2695
@samhocevar
Copy link
Contributor

Hi, sorry for not getting back to you sooner about this feature, but I had trouble building Tiled and then got busy with other things.

The above branch (which I synced with master in #2906) works very well for me. I successfully ported my plugin from Python to JavaScript.

I only came across two minor problems:

  • Image.setColorTable(["#123abc"]) does not work properly, because ScriptImage::setColorTable explicitly casts the array elements to UInt. I have to do Image.setColorTable([0xff123abc]) instead, which is OK but a bit inconsistent with e.g. Tileset.backgroundColor which accepts the "#123abc" argument.
  • calling Tileset.ladFromImage() before Tileset.setTileSize() does not work; the order matters here, otherwise Tiled tries to reload a non-existent image.

bjorn added a commit that referenced this issue Nov 5, 2020
Now a script can create an image, either directly or by loading from a
file or data or based on raw data. Then, the image can be passed to
Tileset.loadFromImage or Tile.setImage.

Related to issue #2695
bjorn added a commit that referenced this issue Nov 6, 2020
Now a script can create an image, either directly or by loading from a
file or data or based on raw data. Then, the image can be passed to
Tileset.loadFromImage, Tile.setImage or ImageLayer.loadFromImage.

Related to issue #2695
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature It's a feature, not a bug.
Projects
None yet
Development

No branches or pull requests

3 participants