My task is to change the icon-color of an icon-image in Mapbox. The only way mapbox allow to do this is by using sdf-icons(https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-symbol-icon-color).
By Hour's of searching i couldn't found the easiest way to achieve this. There is an npm module I found is https://www.npmjs.com/package/image-sdf but after using its command on a png to convert it into sdf and then rendering on a map is not giving me finest results.
The command I am using
image-sdf cycle-initial.png --spread 5 --downscale 1 --color black > cycle.png
cycle-initial.png(INPUT) is below:
cycle.png(OUTPUT) is below:
But while using the cycle.png as an Image src is not giving the finest results.
Code snippet:
const img = new Image();
img.addEventListener('load', () => {
this.mapInstance.addImage('circle-icon', img, { sdf: true });
}, false);
img.src = cycle;
I request if anyone, please help me if I am doing anything wrong here, or is there any correct way to create sdf-icon to render correctly.
After days of research, I think i found the solution. Also, I want to sum-up creation steps of SDF icon's.
First, thing first what is SDF in simple words: SDF is a raster format that is optimised for displaying resized, recoloured, and rotated raster images. They are single color.
Usage: This is my first interaction with SDF in MAPBOX.
Reason is we cannot change the color of icon(if svg or normal raster png) in symbol layer, you have to provide SDF(specialised png) format in order to achieve it.(https://docs.mapbox.com/mapbox-gl-js/style-spec/layers/#paint-symbol-icon-color)
How to create?
image-sdf input.png --spread 10 --downscale 1 --color black > output.png
convert in.png -filter Jinc -resize 400% -threshold 30% \( +clone -negate -morphology Distance Euclidean -level 50%,-50% \) -morphology Distance Euclidean -compose Plus -composite -level 45%,55% -resize 25% out.png
UPDATE
More Detail's: Box is appearing around Icons in Mapbox on sdf = true
What i was doing wrong?
Answer: Before executing the image-sdf command on a png(Please note: it has to be black & white raster path). Resize(Increase) it to around 40-50%.
Like in my case, I resized the normal raster png and the result's were amazing. Have a look. (Please note: I didn't change a word in code and used the same image-sdf command)
Another thing to explore is giving your image a size. I wanted to use an svg for my marker image, and changing:
let img = new Image();
//to
let img = new Image(256, 256);
Gave much better results-
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With