Tool for Palette Swapping/Changing
Hi!
Got a bunch of sprites I'd like to tinker with palette swapping and was wondering if anyone knew of any good tools for that sort of thing?
In the past, I've just sort of done things by hand in the Gimp with a combination of 'select by color' followed by 'flood fill', but have enough images that I'd kind of like something a bit quicker this time.
The idea is simple, take an image with Palette A and create a new image with Palette A', where there is some way to manually specificy a mapping from each color in Palette A to a color in Palette A'.
Thinking specifically of something that allows you to see and set each color mapping individually, and let's you see an A and B version of the image, so you can easily see the mapping and how it affects the image.
Something like a panel showing:
Color A -> Color A'
Color B -> Color B'
Color C -> Color C'
....
plus a panel with: Image -> Image'
Did some googling and came up empty. I don't know if this is something people normally just do within their favorite editor, or if maybe this entire approach is wrong, but I figured I should ask on here before I start down the long and winding path of rolling my own tool for the job.
You can change palettes with GIMP. It doesn't have the preview feature you described and isn't the best UI by far tho.
Gimp: Colors->Map->Set colourmap to change the colourmap.
Sorting the colourmap before by hue ("Rearange Colourmap"->right click->sort by hue) might help to make it a bit easier.
Your current palette contains the string "(imported)". Duplicate that one, change colors like you want, and close the dialog.
There are probably a bunch of other editors which can do that but i could throw together something like you described in a bit in python if there is any interest. (Need to check which GUI toolkit to use before tho).
What you're describing is basically working with "indexed" images, where pixels correspond to a palette index rather than coding for a colour directly. You can use indexed mode in Gimp to work with those. It works ok.
I remember tools like PaintShop Pro and NeoPaint having good palette editing features back in the day, but of course 8-bit images and palettes were more common then. For tinkering with the palette as you describe I would probably write my own dedicated code.
I don't know of any dedicated tool, but something like you describe would certainly be neat as editor built-in functionality.
My somewhat convoluted process using GraphicsGale (full version now freeware, by the way) for indexed images is to copy the section I want to recolour, paste as a new image, perform necessary palette manipulations on new image, copy and paste back into original image. If I've created new colours that I don't want fit back into the original palette I first convert the original image to truecolour, then back to indexed after pasting.
Red warrior needs caffeine badly.
As long as you're dealing with indexed 256 colors or less, GrafX2 can easily do all palette manipulations and remappings you can think of.
Hi all! Thanks much for all the responses!
@Evert: Indexed colors is definitely close to what I'm after, and you're right, Gimp's index color toolset is 'Ok' ;)
@surt: Had not heard of GraphicsGale, but took a look and it looks fantastic, will definitely give it whirl. I guess the idea with your method is that you can quickly check any palette changes against the original since you'd have both versions open in the editor at once.
@DawnBringer: Indeed, GrafX2's 'Swap' button feels tantalizingly close to what I am after.
After sleeping on this for a bit, I came up with some stronger vision for what I wanted and went ahead and viddled something up. Feels a bit like bad programmer hubris as I know somewhere there must be a tool that already does this and much better, but what can I say, guilty as charged. :)
Attaching two screen shots of the tool in action.
Tool shows the original image on the left and the color swapped image on the right.
There's a small window that show's three rows of colors.
First row is the colors in the original image.
Second row shows the corresponding colors in the swapped image.
Third row shows colors loaded from another image or palette file.
First you click anywhere on the first two rows to choose a color.
Then you click on the third row to set what color your chosen color will be swapped to.
The idea is to make it quick/easy convert an image a different palette. So you load in the image, the load in the target palette, then setup a mapping from colors in the original image to colors in the new palette.
In the first screen shot, I have taken the Knight from russpuppy's RPG set (https://opengameart.org/content/rpg-tileset) and converted him to a Sega Master System palette.
In the second screen shot, I've converted him to a NES palette.
On the todo list is a way to save a mapping once you've set it up. And a way to bulk apply a mapping to a bunch of sprite files at once.
OGA doesn't really have a way to post tools, but if anyone thinks this might be interesting or useful for them, I'd be happy to slap together an installer and make it available for download somewhere.
@SleepProgger: GUI Toolkit? Lol, don't I wish! Everything you see there is strictly homebrew. More programmer hubris I suppose, it just seemed faster to toss something together with what's already in my engine then to go find a toolkit and get it up and running, even though I know that's probably not really true...
@DawnBringer: While I've got you on the horn, is there a canonical home for your famous (and wonderful!) DB16 and DB32 palettes? As a side project to this, I am endevouring to compile a set of popular color palette's along with analysis from your Grafx2 toolkit (also wonderful!). Figure I'd post them as a series of entries on OGA. Googling DB16 and DB32 I've only ever found them in message board posts, which works well enough but I thought I'd ask if you'd ever put up an official page for them or anything.
palette_tool_screengrab.png 30.5 Kb [20 download(s)]
palette_tool_screengrab2.png 29.7 Kb [6 download(s)]
Looks good.
For me to be bothered to use something like this outside of the editor it would need to perform many different mappings on different areas of the same image. eg. If I want to do 8 colour variations of a sprite, I duplicate the sprite 8 times in the source file, open it in your tool, select the first copy, fiddle with the colours, select the next copy, fiddle with the colours and so on.
Being able to create new colours is important, rather than being limited to a pre-existing palette.
A nice feature for larger gradient-based palettes would be support for gradient-to-gradient mappings. So mark a sequence on the source palette and a sequence of the destination palette then intepolated the one to the other. Be much easier than individually marking each colour on a large palette and allow adapting between different gradient sizes.
AFAIK the Pixel Joint forums are the original home of DB's palettes.
Red warrior needs caffeine badly.
@surt:
> to be bothered to use something like this outside of the editor
Just want to say I agree with your general sentiment here. There's sort of a high bar before I want to fire up a separate tool for something. There's also the distinct possibility that one might want to edit the output sprite somewhat in order for it to work right in the new palette. To be honest, the whole thing would probably best be done as a script or extension for some existing editor. Indeed, if I was fluent (or had more time to get fluent in) Gimp's Script-Fu or Grafx2's LUA script engine, I'd have certainly tried going that route. On the otherhand, doing it homebrew has at least given me a chance to puzzle out what exactly 'it' is.
> perform many different mappings on different areas of the same image
That's interesting, sort of the inversion of what I was thinking with the bulk application stuff. That's applying one mapping to many sprites. Here the idea would be to apply multiple mappings to the same sprite. Definitely doable. I guess to keep it simple, you'd just set the grid size for the sprites (over even just the row height) and then it'd let you set a mapping for each row. That would be as opposed to something that let you select wholly arbitrary sections of the source image.
> Being able to create new colours is important, rather than being limited to a pre-existing palette.
Interestingly, one of the big 'aha' moments I had thinking about how to lay this out was realizing that I explicitly /didn't/ want to edit the palettes (add/change colors, etc). My use case was pretty narrowly just converting sprites from one palette to another. Still, I can certainly see where this would be helpful for other cases and it wouldn't be too big a deal to add. The idea is you'd be able to alter the palette in the THIRD row, adding or changing colors, etc. Is that what you were thinking?
> support for gradient-to-gradient mappings
Definitely an interesting idea. You're not suggesting that the tool /create/ any colors for the gradients right? Just sort of 'auto-assign' mappings for the gradient. The gradients would have to be arranged in good order in the palette views right?
So you click four colors: start of src gradient, end of src gradient, start of new gradient, end of new gradient
And it sets up a mapping for start of src gradient through end of src gradient to start of new gradient to end of new gradient?
If you picked:
start src gradient = image palette #1
end src gradient = image palette #4
start new gradient = new palette #1
end new gradient = new palette #4
you'd end up with a mapping like:
1->1
2->2
3->3
4->4
and if picked something like:
start src gradient = image palette #1
end src gradient = image palette #4
start new gradient = new palette #1
end new gradient = new palette #8
1->1
2->3
3->5
4->8
and if picked something like:
start src gradient = image palette #1
end src gradient = image palette #8
start new gradient = new palette #1
end new gradient = new palette #4
1->1
2->1
3->2
4->2
5->3
6->3
7->4
8->4
So basically, it either repeats or omits colors as needed.Not too big a deal really, toughest part would probably be GUI'ing it up in a way that makes it clear what the heck you're doing ;)
I was thinking something like this:
A template is just the set of regions with their mappings so they can be reused on multiple sprite/tile sheets following the same template.
Red warrior needs caffeine badly.
Gotcha, that's a pretty good mock-up!
I like the idea that the mappings are displayed in between the two pictures like that.
Having slept on the idea, is region mapping really the right approach? What about a way to simple specify how many different mapping sets you want? Something like this butchery of your very nice mock-up?
The idea is this would save you both the initial step of creating 4 copies of the sprite in your source image and the trouble of defining/saving/loading a set of region maps for it.
I could see other uses for the region mapping concept. For example if you had a sprite sheet with multiple different characters on it, you may want to use a different mapping for each character. But in your case, taking one sprite and spinning off multiple color variants it seems like it would be easier just to tell it 'I want 5 variants'.
Quick questions:
Merge - creates a third color that is: (color1 + color2) / 2?
Revert - restores palette from source file?
Best Fit - selects the closes value in target palette? based strictly on HSV or RGB, or is it worth doing a CIE Delta E Color Difference computation?
Mapping - Remove - if don't specify a mapping for a color what happens? Does it just pass through as itself or does get dropped (mapped to black?)? I guess I prefer the idea that there is always a mapping defined for each color, even if it just points to the same color. Is the idea that you only want to see the mappings that actually change something? Maybe a toggle to show you all the mappings and one to show you just the 'changes'?
whoops, here's that butchered mock up....
colour_remap_tool.png 8.5 Kb [16 download(s)]
Whole sheet colour variants were just one use-case. What if you only want to recolour just the hurt frames in a sprite sheet to flash red?
Merge: yes, replace all selected colours with some kind of average colour. Colour consolidation functionality, so you can remap multiple close colours to a single better fitting colour.
Revert: replace selected colours with the corresponding indices of the source palette.
Best Fit: yep, any colour space is probably good enough to get a base mapping to hand tweak.
Mapping: no mapping just keeps the index as is.
Red warrior needs caffeine badly.
> Whole sheet colour variants were just one use-case. What if you only want to recolour just the hurt frames in a sprite sheet to flash red?
Yeah, I am thinking these are two separate cases with two separate solutions:
Technically, you could mimic the first solution with the second but it's common enough a use case that it probably warrants it's own feature. gotcha on the other points. Hadn't even thought of the color reduction use case! Thanks for all the feedback! I'll work through some of these changes and keep you posted. EDIT -sorry for the horrible formatting on this post, seems to happen every so ofter that OGA just eats all the new lines in a post
I spent a fair amount of spare time over the last day or two recolouring LPC artwork. Having a tool that can easily remap one colour ramp to another would be extremely useful (actually, a Gimp plugin would be the best thing). Bonus points if it can sensibly handle ramps of different length.
@Evert: Yeah, GIMP plugin would be awesome. I've done some script-fu stuff before but nothing this deep. I guess the trick would be figuring out how to get a good persistent interface going, all the GIMP scripting I've done has been pretty minimal on the GUI side, just pop up to get some parameters and then do your magic.
@All:
Well, put some more time into this. It's not done by any means, but figured there was enough there that it'd be worth packaging up for anyone who wanted to give it a go and give me their feedback.
download link at:
http://withthelove.com/ppt/
What's done:
image load/save
palette load
map load/save
multiple map support (one image -> many remappings)
What's todo:
palette editing feature set
palette save
sub-region mapping stuff
gui not as nice as surt's mock up
One note for the folks on here especially, the palettes are ripped directly from the image pixels. Literally, the code scans the image by x then y and builds a list of all the unique colors it finds. What it doesn't do (currently) is read the palette as it is stored in the image file itself. So you may find that your colors don't come in in the order you expect. This is on the 'to be fixed' list.
screengrab1.png 74.1 Kb [3 download(s)]
screengrab2.png 52.3 Kb [1 download(s)]
oh I should also add that it currently displays the RGBA values for the selected color and it's mapping over on the top right of the tool bar. This is kind of a debug feature, it will be replaced by the proper color editing tools when those come in. But for now it at least gives you a way to verify the colors are coming in correctly and can be somewhat useful when dealing with very similar colors.
oh and the color mappings save as flat text files, you can open them up and twiddle them by hand if you like.
oh and note that the color mappings key off of actual RGB values. They are not in any way based off or tied to the palette index of a color. That seemed the 'correct' way to do it to me. It allows you to use the same mapping no matter how the colors are indexed. But if anyone feels otherwise or can think of a good use for using a mapping based purely on index, I'm all ears.
oh and one more thing...
Windows Defender definitely didn't like running the installer, but if you click 'view more' and then 'run anway' it will let you do it.
Runs fine in Wine with the exception of file dialogs appearing behing the main window.
If you don't work with indices then you can't really work with images with subpalettes (NES, SMS, MD, GBC, etc.). If two subpalettes contain the same colour then they'll both be changed.
Working with RGB values could still be useful especially with a similarity threshold for higher colour images.
An option to select between indexed and RGB working modes would be nice.
Preview functionality could be improved considerably.
I figured picking the index from the preview was a given.
Large image is scaled to less than 1x so I can't see individual pixels. Being able to freely zoom and pan preview is a must.
Be nice is there was an option to use the target palette as the destination palette when an image is loaded so it doesn't need to be loaded again seperately.
Red warrior needs caffeine badly.
> Runs fine in Wine with the exception of file dialogs appearing behing the main window.
hey, that's not bad! It's actually using OpenGL 3.0 for all the rendering so double good on Wine that it works!
> If you don't work with indices then you can't really work with images with subpalettes (NES, SMS, MD, GBC, etc.)
Is there a particular image file format that does this sort of thing?
My vision was: if you want to work with NES, SMS, etc. just load up that palette and have at it.
But then I generally work in full 24bit and save as PNG files. I use palettes as a source for colors but I don't actually formally use them within an image editor very often. But I think that's also partly an artifact of the fact that I use GIMP and it's index palette toolset is just 'Ok'.
> I figured picking the index from the preview was a given.
> Large image is scaled to less than 1x so I can't see individual pixels. Being able to freely zoom and pan preview is a must.
Yeah, both on the to-do list. If you didn't try already, you can resize the window to enlarge the preview. Not the same as being able to zoom about but might help until that stuff's done.
> Be nice is there was an option to use the target palette as the destination palette when an image is loaded so it doesn't need to be loaded again seperately.
Yup, also on the to-do list.
thanks for giving it a try! Let me know any other comments that pop into your head!
Not that I'm aware of, I just lay out the subpalettes in the palette in sequence.
Subpalette swapping is use case too, but essentially the same as gradient swapping.
These systems doubly abstract colour values. The display element's (tile or sprite) pixels index into the element's subpalette which in turn indexes into the master palette to get the actual colour value.
Red warrior needs caffeine badly.
@surt:
Gotcha, I think this will come in naturally with index palette support.
Also, yeah, they'll either be a toggle for flipping between mapping by index or by RGB value, or it will be automatically set based on the format of the source file. or both...
@capbros:
As Surt said; PJ is the closest thing those palettes has to a home. I've been thinking about setting up a page for my palettes...but that will have to (at least) wait until the Toolbox v1.4 is released...
Btw. This is what the latest version of the Analyzis-script produces:
analyze21_db32.png 24.8 Kb [14 download(s)]
@dawnbringer: i have v1.3 of the toolkit, is that the current release? The analysis my version produces is missing all the labels, which are very handy indeed! :)
One thought for your script, if possible it'd be nice to see a copy of the palette in it's original (index) order somewhere. Perhaps along the top or bottom? I find the analysis great for suggesting ramps, etc. but I frequently end up going back to source file (typically just a grid of swarches) when I want to pick an individual color. I guess it's just that there's typically some kind of manual ordering to the original palette indices that's useful. Also, I won't lie, that'd also be very handy for my little pet project to bring a bunch of standard palettes to OGA as I could just post a copy of the analysis, instead of the analysis plus a copy of the original palette swatches.
Since you have extensive experience with Grafx scripting, do you think something like this color swapping tool would be possible to implement with Grafx LUA scripts? I'd definitely be willing to give writing a script for it a go if it seemed like something in realm of what the scripting system was designed to handle.
ps
your palettes deserve more than a web site, they deserve a shrine!! :)
Oh, this thread is very relevant to my interests. Being able to choose a ramp and recolor it with a new carefully choosen ramp would be crazy useful. I would also like for this to do is some sort of batch processing (once the colors are chosen being able to just automatically swap those ramps for multiple files would be amazing). Something that probably wouldn't be easy but would also be useful would if I could export a single image with multiple color change options. For example, a sprite with blond hair exported quickly into sprites with red, brown, black, and gray. I would expect that this would only work and really be useful if you could save and load the origin and export ramp setups for multiple images.
I haven't tested out the program you have so far (not currently on my computer) but I'm excited to. Thanks for this!
(I second the motion to get DawnBringer's palettes a shrine! Also some sort of contact info, I've been trying to contact DB for years about possibly building an extension of the 32 palette for easier use in a large RPG tileset I've been making.)
@capbros:
The indexed palette is in the analyzis, but I have now made it clearer and labelled.
Yes, 1.3 is latest (and ancient) offical version if the Toolbox. But if you're interested, you can beta-test v1.4. There's more than 100 new scripts and most old ones have been updated.
The GrafX2 LUA interface/GUI/input options are a bit limited (though I think it's planned to become more advanced in future versions). Although, it is, hypothetically possible to script your own interface, if one doesn't mind the busy-pointer showing while a script is running. However, I haven't seen much suggested in this thread that couldn't already be done in seconds with GrafX2 built-in features (I'm not trying to dissuade anyone from creating another tool, I just want ppl to be aware of the features of GrafX2).
Here are some things you can do with GrafX2:
* Move colors/ranges around in the palette with or without remapping image
* Replace any color (index) with another (image is automatially remapped)
* Copy all or a selection of colors from Main-image to the Spare-image.
* Copy the palette from Main to Spare and have the Spare-image remapped
* Remap a brush with the current palette
F.ex let's say you wanna try variations on a 16-color sprite (index 0-15). Now grab the sprite as a brush. Copy the 16 colors to another place in the palette (maybe 16-31). Now change the original 16 colors to something unused, like full magenta. Now "Recolorize" the brush (it will remap to the perfectly fitting color-copy at 16-31). Now restore the original 16 colors and paste down the remapped brush. You now have two identical sprites, but with different/unique color-indexes. You can repeat this until all 256 colors are used. Now you can tweak the colors of the sprite-copies all you want and see the result/comparison in realtime on the same page.
@Sharm: Ah, yeah. I remember your email. In fact, I was already dabbling with a 64-color expansion of DB32 at the time. I figured I would reply to you when it was finished...suffice to say it's not yet completed! :p
analyze211_db32.png 25 Kb [9 download(s)]
@sharm:
> Something that probably wouldn't be easy but would also be useful would if I could export a single image with multiple color change options. ... For example, a sprite with blond hair exported quickly into sprites with red, brown, black, and gray.
Currently the tool supports exporting multiple color changes but they are all appended into a single file.
So it's:
Source Image -> Many Color Changes -> Single Destination Image (color changes stacked vertically)
If I understand you correctly, you'd be looking to go:
Source Image -> Many Color Changes -> Many Destination Images (one image per color change)
Batch processing is definitely in the works, and for exactly the scenario you are describing: Setup a color mapping, save it out, then apply to multiple images (or apply multiple mappings to a single image). Before I get too far with it, is a command line interface ok for you? That's always how I do my batch stuff but I can look into a GUI interface if folks don't like using the command line.
> I haven't tested out the program you have so far (not currently on my computer) but I'm excited to. Thanks for this!
If you get to running it, any feedback is definitely welcome! Even if it's just that you hate it! ;)
@dawnbringer:
> The indexed palette is in the analyzis, but I have now made it clearer and labelled.
Thanks! It looks great! Label definitely makes all the difference. I would not have guessed that what's that section was, although in hindsight it's kinda obvious.
> if you're interested, you can beta-test v1.4.
Sign me up!! Sounds amazing! Is there a public link for the beta version or is it invite only?
> hypothetically possible to script your own interface, if one doesn't mind the busy-pointer showing while a script is running
Gotcha, thanks for the 411. 'hypothetically' is defnitely the part that scares me. I don't want to get stuck killing myself trying to trick a scripting system into doing something it fundamentally isn't designed for. Still, as I've previously noted, I see major upsides to implementing the idea within the context of an exisiting image editor. That's sort of the conundrum of it.
> I haven't seen much suggested in this thread that couldn't already be done in seconds with GrafX2 built-in features
Thanks for all the pointers! Using the spare actually works pretty well and gets close to my original goal. It's basically as simple as load the image, copy it to the spare, muck around with the palette, flipping back and forth between original and spare to see changes.
Is there a way to load/save add palettes in Grafx2? I couldn't see an obvious way to do it and googling around came up empty.
> F.ex let's say you wanna try variations on a 16-color sprite
I went ahead and tried this and you're right, it totally works!
It seemed a bit tedious at first, but then I realized you could just drag and select all 16 colors to copy at once. That helps alot!
Again thanks for the suggetions. I grew up on Dpaint IV so Grafx2 is right up my alley. Unfortunately, after spending years learning the Gimp, I never been able to justify the effort needed to re-train my brain for a different editor, so this has been a good excuse to spend some time getting to know Grafx2 a bit better.
@all: I took a bit of pause on development over the last few days to spend some time actually using the new tool for some palette work. I figured that was way to figure out what works and what doesn't. Here are my own thoughts so far:
1) I do like it! I know it's tooting my own horn, but for the very specific problem I was trying to address I think it works really well. It's not just that it does the job, but that it's really simple and fast to use. It has got to be just about the fewest clicks possible to do the job. Click source color, Click replacement color. Don't like, click a different replacement color. It makes auditioning different colors and schemes very easy.
I have a huge pile of tile sprites for the game I'm currently working on and after adding/removing/changing things ad-hoc for far too long, I've undertaken a project to review everything, rationalize it and organize it. So far the tool has proven to be a surprisingly big help with this. By 'rationalize it', I mean going through and making sure each area of the game uses tiles that are distinct. Obviously, artistically they are all unique already, but the tool has proven pretty handy for making sure they're all chromatically unique too. I'm struggling to find the words to describe it, but it's a lot of stuff like 'make sure the swampy area uses dark greens and the sunny area uses brighter greens' I know that sounds a bit obvious and something that should be baked into the art to begin with, but I guess what I'm doing is going back and reviewing everything from a 50,000 foot perspective and saying 'ok, how many dark green areas do I have? are there too many? are these two dark green areas too similar? should I go back and recolor something so the two areas are more distinct?' Having a tool that can quickly swap colors around has proved pretty handy. I've even had a few cases where I got into the tool, fiddled a bit and realized I could totally repurpose something just by recoloring it and moving it to a different area.
2) Being able to quickly create/work on/switch between multiple re-mappings at once is very handy. I find myself making some changes, hitting 'Clone' and then making some more. So I'm sort of iterating through different options, using the previous mapping as the starting point for the next. When I'm done, I go back through and keep the best options and toss the rest.
3) Showing just the colors that are being changed is also very handy.
So thanks very much to surt for pushing both of those ideas!
4) 'picking the index from the preview' would definitley be very nice! Had always intended to add that but now am a bit ashamed I didn't deem it essential as it's definitely a pain to work with out it.
5) Needs a 'Load/Save Project' feature. Something that saves the entire current state (src image, palette, and all color mappings) and let's you load it back in later. Bascially, so you can quit the app and pickup again where you left off later.
Quick question for the gang about this. My initial thought is to implement this as a simple text file that just records the location the the source image and palette (c:\my stuff\picture.png, etc) and a list of all the current color maps. Does anyone see a good reason to try and imbed the images and palettes into the project file? Seems like a hassle and a waste of space to me, but it would technically make the project files more portable.
Some bug notes:
No idea why it's window seems to stop responding to move and resize clicks sometimes. Clicking around on some other windows and then back to the tool does seem to fix it though. I suspect this bug has something to do with SDL and the built in windows file browser dialogues not playing nice together. Will do my best to sort it out.
Definitely chugs power on my laptop! Apologies to other laptop users out there! This largely an artifact of the tool using my game engine, meaning the rendering is done with OpenGL and the core loop is pretty much always trying to run at full throttle, even though 90% the app is going nothing and could probably get away without even updating the screen. Will definitely take a poke at what might be done to make it smarter about this but no promises.
My current 'to-do' list, in rough prioirty order, or at least in the order I was figuring to tackle them (some being larger undertakings than others):
select color from preview
zoom/pan in preview
toggle to load palette with image
load/save project
basic command line batch processing
palette modify/add/edit
index palette support (displaying palette as indexed in image file)
palette ramp mapping tools
region specific mapping
@Capbros: Ah! I really love this! I'm totally going to be using this a lot, thank you so much! It would be a little easier to use if I could rearrange or load the palette for the beginning image, if it's at all possible. Right now the way it loads in can be confusing to figure out the ramps. I really love how I can load a secondary palette and choose how the colors get remapped, it's very fast and easy to see what I'm doing.
I'm not a programmer at all so the more gui you can make things the better for me. Now that I've had a chance to play with it I see how the multiple color changes work. That's really cool.
I'm fine with needing to load the palette information separately but doing it all at once has less potential for confusion.
@DawnBringer: You did get my message! I had no idea if that email I found was even legit and after I sent it I realized I might have accidentally called you DawnBreaker instead and felt like an idiot. I don't mind waiting, though I may end up finishing the art I wanted it for before you're done. ;) Honestly, the current one is working pretty well, it's an amazing palette. I just would like a little more flexibility in the reds and purples and one more medium brown where the orange currently sits. I could do it myself but I want a legit version with your knack for careful choices working in multiple ramps.
@capbros:
Your program is getting ambitious! :D
>Sign me up!! Sounds amazing! Is there a public link for the beta version or is it invite only?
Message me an e-mail address and I'll send you a link when the next test-version is ready.
>Is there a way to load/save add palettes in Grafx2? I couldn't see an obvious way to do it and googling around came up empty.
Usually you would just load/save an image with the palette(s) you want. There is at least support for the .pal format (see Format droplist in Load/Save). My Toolbox have a bunch of preset palettes. I've also got a script that takes the current palette and creates a new palette-setting script. If you mean holding palettes available...there's only the main & spare-page palettes (the brushes also have their own colors that can be retrieved, but it's a little messy to work with).
@Sharm:
Well, if you like, you could take a look at the current DB32+32 and see how it feels.
@Dawnbringer:
> Your program is getting ambitious! :D
I know! I am trying to be careful not to over do it as it's just meant to be a quick little tool and I do still have a game to make. So far, I think it's going ok, but please stop me if I start adding any drawing or image editing features!
> Message me an e-mail address
Done! I actually have a small idea for a script I've been meaing to write as Script-Fu for a long time. Think I'll use this as an excuse to learn some LUA and do it as a Grafx plugin instead. The concept is something that automagically colors the invsibile (alpha=0) pixels around a sprite by sampling the nearby visible pixels. Editors tend to leave junk or black in invisible areas, this can bleed into the sprite itself if you apply any filtered scaling/rotation to it. Filling invisible pixels instead with color sampled from the near by visible pixels minimizes the impact of this 'bleeding' and yields pretty nice results (at least with standard bilinear texture filtering). I actually have a stand along program I've written that does this, along with re-gridding sprites. Just some code I wrote a few years back, but when I saw your scripts can do re-gridding (changing from say 16x16 to 18x18 grid) I thought 'this is a better place to do that alpha coloring thing...'
@Sharm: Glad you like the program!
> It would be a little easier to use if I could rearrange or load the palette for the beginning image
I think I hit both of these in the new update, let me know if it works/helps/make sense.
> the more gui you can make things the better for me
Ok. I think my approach will be: command line batch commands plus a GUI front end for them. Hopefully that will work out to be the best of both worlds :)
@all: Squeezed a little development time in this weekend, and so...
PixelPaletteTool Version 1.2 available at:
http://withthelove.com/ppt/
Adds support for:
select color from preview
zoom/pan in preview
load/save project
rearrange colors in palette
save palette as image
preserve palette order when loading indexed format images (display palette as indexed in image file)
Some notes:
you can pan about with the sliders, or by holding space and moving this mouse (Gimp style).
you can select a color by clicking on either the original or remapped images. In either case you get the color from the original image. In other words, if you have remapped black to white, clicking white on the remapped image will select black. That might seeem counter-intuitive but after using it a bit I found this to be the best approach. Think of it as selecting what mapping you want to adjust not really the color. If it helps, think about how it should work in the indexed image case, you'd want to select by index not color.
you can re-arrange the palette swatches however you like. You'll lose the order if you reload the image or load a new image (even one with the same palette). BUT the order is saved in the project file, so if you get an order you like, you can keep it that way (or for the swap palette by saving it). Also the order for the source image palette and new palette are held separately, so reloading one won't affect the other.
Will work on the ability to keep a custom order when loading a new image, as with 'toggle to load palette with image' it's mostly a matter of how to present it in the GUI.
Note that clicking on a swatch in the 'Palette' area always sets the map for the currently selected color. This is true even if you are clicking to drag the swatches around. To keep this from being a problem, I've made it so that if you click on any empty space it will clear the current color selection (so no color is selected.) Technically, this does penalize errant clicks a bit, want to use for a bit to see if that's a big problem, didn't seem to be in testing.
When viewing multiple mappings, zoom is a bit funny. It truncates the view rather than shrinking it. Makes optimal use of the space but not quite the behavior I'd expect. Working on it...
The debug text showing RGBA for the current color and map is still there, don't worry it will go away (or be made to look nice) someday!
Well, that's all for this update. Think I largely maanged to stick to my original priority order. Here's the todo list in the current order I'm thinking of tackling it:
toggle to load palette with image
toggle to keep custom palette order when loading new image with same palette
palette modify/add/edit
palette ramp mapping tools
index palette support (edit/map by index instead of color)
region specific mapping
command line batch processing
GUI frontend for batch processing
Attaching a screengrab that shows pan/zoom and dragging to rearrange palette in action.
pixel_palette_tool_1_2_preview.png 67.6 Kb [6 download(s)]
@DawnBringer: I would love that!
@Capbros: Swaping the colors around works great. Being able to set things up so that they make sense to me like that is very helpful. The solution for not swapping colors while moving things around was completely intuitive, I had no problems with it. I think the additional support for selecting the color from the preview added a bug. Now when I try to move my mouse above the preview window it won't let me and I get an odd double cursor. The top cursor goes above the preview but seems to not function at all.
Index color support would be severely cool, I started out back when index was the only option and I've been missing the fun tricks you can do with a controlled index pallet for years. Modern stuff just doesn't allow you to do things like paint an image with two of the same color but different indicies. I still won't be able to do anything that displays the fun palette tricks without another programmer, but getting it set up in the first place would make some things possible that aren't right now without a DOS program.
EDIT: The cursor bug went away when I closed and opened the program. I haven't been able to recreate it.
EDIT 2: Managed to recreate the bug, but I'm not certain what causes it. It only shows up after you've loaded an image, it doesn't do it on the preloaded picture. After it's loaded it's fine, but once you interact with it at all like zooming in or swapping a color, that seems to be when it happens.
Preview zoom scales with window size, listed view scale doesn't change.
Panning doesn't seem to be happinging in screen space so when zoomed it doesn't track intuitively with mouse cursor.
Being able to zoom out below 100% then zoom at mouse cursor would be handy for navigating large images.
Mousewheel zoom with MMB pan would be nice.
Here's the relevant code from one of my projects for mouse-view-transform-as-I-like-it, feel free to steal (QTransform is just a 3X3 transform matrix):
void ImageEditor::rotateScaleAtPoint(QTransform &transform, const qreal rotation, const qreal scaling, const QPointF point)
{
const QPointF pointBefore = (transform.inverted()).map(point);
transform *= QTransform().scale(scaling, scaling) * QTransform().rotate(rotation);
const QPointF pointAfter = (transform.inverted()).map(point);
const QPointF offset = pointAfter - pointBefore;
transform = QTransform().translate(offset.x(), offset.y()) * transform;
}
bool ImageEditor::handleMouseEvent(const Qt::KeyboardModifiers modifiers, const Qt::MouseButton button, const QPoint pos)
{
const QPointF lastMouse = mouseTransform.map(lastMousePos);
const QPointF mousePos = mouseTransform.map(pos);
const QPointF pixelCoordF = viewTransform.inverted().map(QPointF(mousePos));
const QPoint pixelCoord(static_cast(floor(pixelCoordF.x())), static_cast(floor(pixelCoordF.y())));
const QSet states = mouseState.machine.configuration();
if (states.contains(&mouseState.leftToolState)) {
setDocumentModified();
}
else if (states.contains(&mouseState.leftPickState)) {
}
else if (states.contains(&mouseState.rightToolState)) {
}
else if (states.contains(&mouseState.rightPickState)) {
}
else if (states.contains(&mouseState.panState)) {
QPointF translation = QPointF();
translation += mousePos - lastMouse;
viewTransform *= QTransform().translate(translation.x(), translation.y());
update();
}
else if (states.contains(&mouseState.rotozoomState)) {
qreal scaling = QVector2D(mousePos).length() / QVector2D(lastMouse).length();
qreal rotation = qRadiansToDegrees(atan2(mousePos.y(), mousePos.x()) - atan2(lastMouse.y(), lastMouse.x()));
rotateScaleAtPoint(viewTransform, rotation, scaling, QPointF(0., 0.));
update();
}
lastMousePos = pos;
lastPixelCoord = pixelCoord;
return true;
}
void ImageEditor::wheelEvent(QWheelEvent *event)
{
const qreal delta = event->angleDelta().y() / (15.0 * 8.0);
const qreal scaling = pow(2, delta);
const qreal rotation = -15.0 * delta;
if (event->modifiers() == Qt::NoModifier) {
rotateScaleAtPoint(viewTransform, 0.0, scaling, mouseTransform.map(event->posF()));
update();
}
else if (event->modifiers() == Qt::ShiftModifier) {
rotateScaleAtPoint(viewTransform, rotation, 1.0, mouseTransform.map(event->posF()));
update();
}
event->accept();
}
Red warrior needs caffeine badly.
@surt:
yeah the zooming is a bit tweaked. It's built around the idea of defaulting to filling the display area. So if you grow the window the preview will always rescale to fit whatever space you have. Personally, I like that style but I can see where be results might be counterintuitive at times. I'll see about making that a toggle or a 'fit to screen' button.
And yup, currently the panning is based on a % idea as opposed to an absolute pixel concept. So the movement is not 1 to 1 with the mouse and will move at different speeds for different image sizes. You were expecting it to be more 1 to 1 with the mouse? So 1 pixel moved on the mouse moves one pixel in the preview image?
Let me ask if these are observations of the 'it's not what I was expecting but it works well enough' variety or the 'oh god it's so painful, it hurts to use it' variety?
MMB move definitely coming, probably scroll wheel zoom also, although that I can't promise without checking on sdl's support for it.
@sharm: Pretty sure I have encountered this nefarious 'dead cursor' bug as well. Is what you're see a black cursor that doesn't respond to clicks on the window frame (titlebar and wwindow edges, for moving and resizing rhe window)? Inside the app the mouse still works just fine? have definitely had that and yeah it seems to comeon only after loading an image or palette. I believe ot is a bad interaction between SDL and the windows file browser code. Haven't had time to go spelunking for a fix just yet but have found that clicking off the app window (like say onto the desktop) and then clicking back on the title bar for the app seems to clear it up, at least until it strikes again.
If indexed colors is what you crave, you've got to try Grafx2, it'll take you right back to Deluxe Paint land!
As DawnBringer points out it has a lot lf great functionality for index palettes built in, and then there's all the tricks his toolbox scripts bring.
@all: thanks for the continued feedback! Sorry for the slow responses, took time last week to convert the tool into a game I submitted to the OGA summer game jam. Back at it this week, hope to have an update soon.
Yep, that's the same bug. It's not too annoying but I thought you might want to know. The first time I encountered it clicking away and back didn't help, maybe I'd been running it broken longer or did something to complicate the error. I'll let you know if I figure it out.
Oh, didn't know that about Grafx2. I'm just going to have to eventually collect all the pixel programs aren't I? Thanks for the heads up.
My problem with the zoom is that there doesn't seem to be a way to move what's showing in the zoom window and zooming in always zooms the exact same spot. Because of that if there's something I want to color pick from on the bottom right corner of a larger image, I won't be able to. My guess is that this is Surt's problem as well.
When you zoom sliders should appear on the edge of the preview image.
you can move these to pan around the zoomed image.
alternately you can pan by holding space and moving the mouse.
sliders are a bit non-descript so perhaps you missed them, or are they not appearing for you? That would definitely be a bug!
thanks for reporting the cursor bug btw, definitely appreciate hearing about it even though I'd already seen it myself. At the very least you've confirmed that it isn't just an issue on my particular versions of windows, video driver, etc.
i have found clicking off the window and then specifically on the titlebar clears the issue up. Something about the titlebar seems to jossle the bits back into order...
It looks quite neat. I'd love to give this a go, but unfortunately (?) I don't have Windows. I'm guessing your program is Windows-only? Or is there a chance for a Linux/OS X version?
Oh! Yep, I totally missed that. I have the sliders. The spacebar thing works too.
The mouse panning in image-space rather than screen-space is certainly in the "oh god it's so painful, it hurts to use it" category. Better not to use the mouse for panning at all in that case.
If the program tells me the preview is at 100% zoom then I absolutely expect that to be the case.
The others are in the "it's exactly what I was expecting (standard practice) but it not the way I think it should be done" category, I won't even mention scrollbars for 2D scrolling.
If you aren't going to have zoom-at-mouse then ideally allow panning beyond the edge of the image (place zoom origin anywhere on the image) so the user can still navigate by zoom out, pan, zoom in.
Red warrior needs caffeine badly.
> mouse panning in image-space rather than screen-space is certainly in the "oh god it's so painful, it hurts to use it" category. Better not to use the mouse for panning at all in that case.
...
> If the program tells me the preview is at 100% zoom then I absolutely expect that to be the case
Gotcha, I was asking so I could properly prioritize working on it vs adding new features. As it happens, they were both pretty easy fixes, just a bit of math to convert things around. And you're right, it's much better now. Funny, I wouldn't have said either of these really bothered me the way they were, but using it with them fixed that I can see why you'd find the old way annoying.
Thanks again for the feedback!
I've been working on adding 'palette modify/add/edit' features and want to wait until they're ready before rolling up a new build. Hope you're ok waiting that long for the zoom/pan fixes.
> I won't even mention scrollbars for 2D scrolling
lol, yeah these are also % based. I have tweaked them slightly since the last build (they now stay on the edges of the preview area instead of hugging the preview image itself), but it's unlikely they'll ever look (or work) like the ones in your mock up. Programming a proper scrollbar that resizes itself accoring the image and the zoom level is simply way out of scope for this project. A sad artifact of the whole GUI being strictly home-brewed instead of using a proper GUI toolkit and a good lesson in why rolling your own is never really the right idea...
@Evert:
Linux build is not out of the question. Code base is entirely C# and SDL which makes a Linux port theoretically possible. The key issue is time. My plan is to finish my current game project and then spend some time porting the engine to Linux, at which point a Linux port of PixelPaletteTool would be possible also. But my current game project has been under development for 3 years and counting now, so it might be a while...
Hi all!
Just wanted to say I haven't abandoned this project yet.
I am down the path of proper index palette support and palette editing, but I can see it's a much bigger change than I had originally anticipated. In a nut shell, the whole thing is based off the idea of matching RGB color values and switching it out to match color indices instead is non-trivial operation. So those features are definitely going to take a while longer to come about.
That being the case, I have gone ahead and rolled a small update (Version 1.3) that contains just the GUI changes (zoom/pan) that surt had petitioned for (one-to-one panning, scroll wheel zoom, true zoom %, etc).
You can find the update here:
http://withthelove.com/ppt/
For itch.io fans, I've also added a proper itch.io page for the project here:
https://capbros.itch.io/pixelpalettetool
I have been using the tool quite a bit as I work on stuff for my current game project. It's sort of worked it's way into my tool chain. I find it kind of liberating actually. When creating something, I no longer worry too much about getting the colors exactly right, I just focus on getting the general look and number of color right, then I'll go back and use the tool quickly preview a bunch of different coloring options and choose the best one.
I also find it very handy for tuning two pieces to work well together. For example, maybe you have a cave wall tile from one tileset and a floor tile from a different tileset, with a little color shifting, they can usually be made to match well enough to work as a new combination.
Well, I guess I'm just tooting my own horn here, so I'll stop now. Suffice to say, I find this tool pretty handy and am thankful for everybody's help and input on it.
Yay! I'm going to have to follow you on itch.io now. :) Thanks for the update!
This tool looks really neat; could you release the source code? I would like to play around with it.
@congusbongus: thanks! I haven't released the code for this yet, because I haven't had the time to go find a good license to use and package everything up all nice for folks. Still, if you're interested, I can try to put some time into doing that. Fair warning though, the code base for this one is pretty wonky. It's a really weird mix of some custom game engine stuff I wrote to support dynamically recoloring sprites and then repurposed for palette swapping, plus a bunch of home made GUI crud.
Having proved the idea out, I'd really like to rewrite the whole thing from the ground up with a standard GUI tool kit like GTK. But it'll definitely be a bit before I have time to do that. :(
Hi all!
Just wanted to let folks know that this project isn't dead!
Still no proper index palette support or color editing, but based on some nice feedback from Chasersgaming, I've gone ahead and rolled up a new version with a few small changes:
Added option to change background color (default is black).
Separate initial paths maintained for save/load image/palette/project file browsers.
(Previously, all save/load file browsers used same initial path variable)
Added a small selection of useful palettes to project distribution,
these can be found in the 'palettes' subfolder of the install folder.
Load palette dialog defaults to starting in '[INSTALL_PATH]/palettes'.
Colors with alpha values less than 255 removed from palettes.
Only unique colors loaded from images/palettes (roll back of previous and broken support for indexed images/palettes).
Support added for reverse color selection (clicking swap color and then match color.)
Download at:
https://withthelove.itch.io/pixelpalettetool
On the long term front, I have put some time into wrangling GTK so there is still hope for a version with a proper GUI down the road, just have to clear some other stuff off my plate first.
I saw the update on itch.io first. That's awesome! I'm glad you're still working on this, I love this tool.
I was looking around the internet for a palette-swapping tool, and this appears to be almost exactly what I was hoping for! Thank you for making it and putting it out there for people to use.
@karmicRetribution: Thank you! Let me know how the tool works out for you. I was in exactly your shoes when I wrote the program, so if it can keep one more person from having to write their own utility for doing palette swapping I can die a happy man. :)
I did unearth a bug this morning where the debug text showing the raw RGB values for the colors can get confused. So I will probably be rolling out a minor bug fix release soon, so if you run into any issues or have any feedback for me, don't hesitate to let me know.
Well if you're going to be tinkering in it anyway... it would make me very happy if there was an option to display hex colors instead of/in addition to RGB, since that's what my programmer needs for the projects that I'm working on.
@karamixRetribution: Can do! Haha, those programmers and their crazy hex ways! :)
@karamixRetribution: Took a bit longer to get to this than I was expecting, but ask and you shall recieve!
https://withthelove.itch.io/pixelpalettetool/devlog/84354/pixelpalettetool-v151-released
Ohmigosh! I wasn't watching the email I have attached to this account. Thank you so much, this looks great!!! It will definitely simplify my workflow.
mtpaint is capable of loading gimp's .gpl palettes and therefore easily swap palettes in indexed 8bit .png
https://github.com/wjaguar/mtPaint
Pages