twolfson / gulp.spritesmith

Convert a set of images into a spritesheet and CSS variables via gulp
The Unlicense
1.07k stars 81 forks source link

How to set background color for jpg? #33

Closed denisz1 closed 9 years ago

denisz1 commented 9 years ago

It auto generates a sprite with a black background. Since I use padding between images, and need to place the images on a white background, I need that bleed area to be white.

There is no documentation, so I dug through the source. From gulp.spritesmith to spritesmith to pixelsmith to save-pixels... :)

Is this possible?

denisz1 commented 9 years ago

In fact, now that I think of it, how do you control options for the engine in general? The docs say you should consult the engine, which I understand is pixelsmith, but there are no options I can find. :(

So are there options for quality, etc., as well?

twolfson commented 9 years ago

That should be possible with pixelsmith/save-pixels since we can fill the ndarray with a specific set of pixel values. However, if you need aliasing (e.g. you have semi-transparent pixels from a PNG being saved to a JPG), then it would be harder to add since there are more possible variations. Do you need aliasing?

twolfson commented 9 years ago

pixelsmith has no specific options, hence the lack of documentation. In contract, gmsmith documents its options here:

https://github.com/twolfson/gmsmith/tree/0.4.5#canvasexportoptions-cb

denisz1 commented 9 years ago

@twolfson So pixelsmith allows setting bg color, and gmsmith allows quality but not bg color. Choices, choices! :-) Ok lemme use pixelsmith and forget about the quliaty option.

No I don't need aliasing, I want to sprite a bunch of jpgs. If I output a jpg sprite then its size is 10% that of a png. But of course png has alpha channel, and jpg does not, hence the need to set the bg color for jpg.

I dug into save-pixels and it seems complicated to override as there are no options to config the thing. Maybe I should just stick with png and force my users to upgrade their internet connection :)

It uses jpeg-js under the cover, which seems to set bg color via the canvas before superimposing an image on it (I think), but there doesn't seem a configurable way to get at that part of the code. So it doesn't seem possible.

twolfson commented 9 years ago

It's definitely possible. In pixelsmith's canvas we define our ndarray. By default, this is filled with all zeroes that represent an rgba of rgba(0, 0, 0, 0) aka transparent black.

https://github.com/twolfson/pixelsmith/blob/1.0.0/lib/canvas.js#L13

Since jpeg's don't support transparency, the alpha channel is dropped and it becomes rgb of rgb(0, 0, 0) aka opaque black.

To support your use case, we can fill all of those values with specific rgba value before overlaying the images (e.g. rgba(255, 0, 255, 255) for hot pink). This can be done most easily with ndarray-fill:

https://www.npmjs.com/package/ndarray-fill

I will take a look at adding in support by the end of this weekend.

denisz1 commented 9 years ago

@twolfson Sure, what I meant is not that it's not possible (whoa too many double negative there), but there was no configurable way for me to do it, save a mod to the underlying source.

If you decide to look into it, maybe consider having it as an option, so a user can pass in an (optional) rgba value? That would make it useful to the greatest number of people. I think black and white are the most used, but might as well make it configable?

Now I understand what you meant in that other thread, about maintainability. So many interconnected projects, wow!

twolfson commented 9 years ago

Taking a shot at this now

twolfson commented 9 years ago

I added it in via background for the exporter in pixelsmith@1.1.0. Corresponding spritesmith family releases will happen shortly. For your usage, you can use:

{
  // imgName, cssName,
  imgOpts: {
    background: [255, 255, 255, 255] // opaque white
  }
}
twolfson commented 9 years ago

The upgrade has been installed in spritesmith@1.3.0, gulp.spritesmith@3.2.0, and grunt-spritesmith@4.2.0. Thanks again for the feature request =)

denisz1 commented 9 years ago

@twolfson Works well on this side... thanks!

PS it's [255,255,255,0] for opaque white, for any who stumble on this thread.

twolfson commented 9 years ago

Eh, [255, 255, 255, 0] will only work for JPEG's since they ditch the alpha channel. You will want to use [255, 255, 255, 255] for other cases like PNG's.

denisz1 commented 9 years ago

@twolfson Yes you're right... didn't test it properly.

twolfson commented 9 years ago

Interesting since we use 255 as the alpha during tests which works:

https://github.com/twolfson/pixelsmith/blob/1.1.0/test/pixelsmith-test.js#L109

https://github.com/twolfson/pixelsmith/blob/1.1.0/test/expected-files/background.jpeg

I am going to double check with a white background and PNG to verify supporting all cases.

twolfson commented 9 years ago

Ah, nvm. Saw your edit =)