Tiled palette quantization tool

Discussion of hardware and software development for Super NES and Super Famicom. See the SNESdev wiki for more information.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
GValiente
Posts: 11
Joined: Mon Sep 12, 2022 12:17 am

Re: Tiled palette quantization tool

Post by GValiente »

Rilden wrote: Sat Sep 17, 2022 1:31 pm I can make the output save as an indexed color bmp when clicked.
That would be great, thank you.
User avatar
Individualised
Posts: 310
Joined: Mon Sep 05, 2022 6:46 am

Re: Tiled palette quantization tool

Post by Individualised »

This may seem like an unorthodox request, but is it possible to add a "load from URL" option to this tool?
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Tiled palette quantization tool

Post by tepples »

That depends on whether the URL to be fetched supports Cross-Origin Resource Sharing.
turboxray
Posts: 348
Joined: Thu Oct 31, 2019 12:56 am

Re: Tiled palette quantization tool

Post by turboxray »

Code: Select all

        for (let i = 1; i < numPalettes; i++) {
            const p1 = palIndex[i] - 1;
            const p2 = palIndex[i + 1] - 1;
            let iteration = 0;
            while (iteration < tIterations) {
                const index1 = Math.[b][i][u]max[/u][/i][/b](startIndex, Math.floor(Math.random() * numColors));
                const index2 = Math.[b][i][u]max[/u][/i][/b](startIndex, Math.floor(Math.random() * numColors));

I had converted worker.js over to python. I ran into an issue where the above code would result in index1 or index2 actually equaling numColors.. which causes an index out of bounds for index1+1, etc. I'm not sure if it's a precision error thing, as the python and JS docs both say random() should never give a value of 1.0. But I simply added a -1 to the floor() value to fix it.

If it is a precision error thing, and if it does happen on the worker.js too... does it behave like frontend JS?? As in it just jumps out of that section of the code, but continues on (it's been a minute since I've done any full stack work, but I vaguely remember JS doing weird stuff like that - not fully halting on errors).

Also, the python version is about 8x slower than the JS version. I wasn't expecting that.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Tiled palette quantization tool

Post by lidnariq »

All web browsers' javascript implementations have been compilers for at least the past ten years, if not 15. With Python, you're "supposed" to use Cython or Pypy, although I've heard there are people in looking into adding a JIT to the standard CPython implementation.
turboxray
Posts: 348
Joined: Thu Oct 31, 2019 12:56 am

Re: Tiled palette quantization tool

Post by turboxray »

lidnariq wrote: Thu Jan 05, 2023 5:11 pm All web browsers' javascript implementations have been compilers for at least the past ten years, if not 15. With Python, you're "supposed" to use Cython or Pypy, although I've heard there are people in looking into adding a JIT to the standard CPython implementation.
There already is a JIT for python; Numba. But it's not compatible with all data structures - from my experience it needs code written for it, or extensive refactoring (even though it looks as simple as just using a decorator). Cython and Pypy aren't 100% python/library compatible. I feel most people use numpy/pandas/scipy... but you only get a performance boost when you keep the data in their structures (not pull it and do "python" stuff on it) and performance operations on it via same interface ("functional instructions", or usually something akin to linear algebra). Or something like boost to dynamically link a C++ DLL to python.

Yeah, I knew JS was optimized in browsers with a JIT.. but it was never fast haha. At least, not for how this code was written.

Anyway, I guess I'll convert it to C++ and see how it fairs against the original's speed.
User avatar
Terwilf
Posts: 11
Joined: Tue May 29, 2018 3:23 pm

Re: Tiled palette quantization tool

Post by Terwilf »

Hi, I love your app, it has really changed the way I work, and I wonder if in the future it might not be possible for me to make an offline version, so I can continue using it when I don't have data. If this is not possible, I understand.

On the other hand, after using it for a while, I have realized that the intermediate results in the "Dithering (Slow)" mode are much better than converting the image normally, the problem is that since it is not saved, I have to capture it again. External form, with a very high FPS rate.

An option to be able to keep each iteration of the image (but without the dithering effect) would be great.

And although this is no longer relevant, although the application is very useful for deciding how to apply the color attributes, using this information to divide the image into groups, I get better results by reducing the colors of each of them with "Simple palette quantizer ", usually with the "Wu's color quantizer" method. I don't know if this information is useful to you, finally, simply, thank you!
calima
Posts: 1745
Joined: Tue Oct 06, 2015 10:16 am

Re: Tiled palette quantization tool

Post by calima »

You can probably make an offline version for yourself. Download the page and JS, edit any references to be local.
Rilden
Posts: 21
Joined: Wed Jun 22, 2022 5:34 am

Re: Tiled palette quantization tool

Post by Rilden »

The simplest way to make it work offline is the following:
- download the files from https://github.com/rilden/tiledpalettequant
- go to the folder where you put index.html and the rest of the .js and .css files
- open a terminal and type python -m http.server
- open a web browser and go to localhost:8000
You need to have python installed. For more info check out https://developer.mozilla.org/en-US/doc ... ing_server
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Tiled palette quantization tool

Post by lidnariq »

There's lots of other very-light-weight static website host daemons, including busybox.

You could also use nwjs to convert a javascript-and-html-only webpage into a program.

I suspect it should be possible to write a little bit of code to run the converter as a command-line program using node, too.
SNES AYE
Posts: 201
Joined: Mon Nov 07, 2022 11:28 am

Re: Tiled palette quantization tool

Post by SNES AYE »

OK, so just to check, the setting for an image made to fit within the limitations of Mode 1 on SNES (one of the ones that can use 128 colours total, 120 visible) would be:

Tile width = 8
Tile height = 8
Palettes = 8
Colours per palette = 16
Bits per channel = 4? (Is this the same a bpp?)
Fraction of pixels = ? (No idea what this is)

Colour index zero behaviour = Not quite sure how each of these should be considered in relation to the image.

Dithering = Whatever I prefer
Dither weight = Whatever I prefer

Dither pattern = Whatever I prefer

Is that correct?
Last edited by SNES AYE on Thu Feb 09, 2023 4:49 am, edited 1 time in total.
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Tiled palette quantization tool

Post by 93143 »

SNES AYE wrote: Wed Feb 08, 2023 11:47 pm Colour index zero behaviour = Shared colour? (Why this one?)
Because if you're only using a single BG layer, any pixels with colour index 0 will let the backdrop colour show through. Ignoring colour math for simplicity, the backdrop colour is CGRAM #0, which means that the first colour in BG subpalette #0 is effectively shared by all the other subpalettes. In other words, 121 colours are visible, not 120.
Tile width = 8
Tile height = 8
You can of course use 16x16 tiles on SNES, but unless you're short of VRAM or DMA time there's not generally much point.
SNES AYE
Posts: 201
Joined: Mon Nov 07, 2022 11:28 am

Re: Tiled palette quantization tool

Post by SNES AYE »

93143 wrote: Thu Feb 09, 2023 4:48 am
SNES AYE wrote: Wed Feb 08, 2023 11:47 pm Colour index zero behaviour = Shared colour? (Why this one?)
Because if you're only using a single BG layer, any pixels with colour index 0 will let the backdrop colour show through. Ignoring colour math for simplicity, the backdrop colour is CGRAM #0, which means that the first colour in BG subpalette #0 is effectively shared by all the other subpalettes. In other words, 121 colours are visible, not 120.
Tile width = 8
Tile height = 8
You can of course use 16x16 tiles on SNES, but unless you're short of VRAM or DMA time there's not generally much point.
OK, thanks.

And regarding the two other things:

Is bits per channel just the same a bpp? If not, what is this for?

What is the fraction of pixels setting for?
93143
Posts: 1717
Joined: Fri Jul 04, 2014 9:31 pm

Re: Tiled palette quantization tool

Post by 93143 »

SNES AYE wrote: Thu Feb 09, 2023 4:53 amIs bits per channel just the same a bpp? If not, what is this for?
That's RGB resolution. The correct setting for SNES is 5.
What is the fraction of pixels setting for?
Rilden wrote: Tue Sep 06, 2022 7:10 am Pixel fraction controls how many pixels are processed per step. With a smaller number the conversion is faster, but the result has a lower quality.
Rilden
Posts: 21
Joined: Wed Jun 22, 2022 5:34 am

Re: Tiled palette quantization tool

Post by Rilden »

Bits per channel is 2 for sms, 3 for megadrive, 4 for game gear, 5 for snes, gbc, gba.
Color zero behaviour:
- unique: each subpalette can have a different color at index 0
- shared: color zero is shared by each subpalette, this color will be assigned to pixels with similar color (not just the exact color chosen)
- transparent color: color zero is transparent, this color will be assigned only to pixels with exactly this color
- transparent, from transparent pixels: color zero is thansparent, this color will be assigned to transparent pixels
Use unique for gbc or sms.
Use shared if your image will be used on the bottom layer and you don't want to draw anything behind it. You can click on the color to change it.
Use transparent color if you want to treat a color in the input image as the transparent color.
Use transparent, from transparent pixels if your input image has transparent pixels (the input is in rgba format and the pixel's alpha value is zero).
Post Reply