Mathematica language newbie here. I wrote the following code to quantize an image:
basepath = "~"
SetDirectory[basepath]
jpgpath = FileNameJoin[{basepath, "jpg"}]
pngpath = FileNameJoin[{basepath, "png"}]
domquant[path_, n_] :=
Image[{List @@@
DominantColors[Image[ColorQuantize[Import[path], n]], n]}]
(*Convert each jpg in path to its 256-color quantized sample*)
Scan[( \
img = domquant[#, 24];
Print[#, " ", img];
Export[
FileNameJoin[{pngpath, StringJoin[FileBaseName[#], ".jpg"]}],
img,
"JPEG", ImageResolution -> 300,
ImageSize -> {8192, 512}]) &, {FileNames[
"*.jpg", {jpgpath}][[1]]}]
If I change the 24 in the domquant
call to a higher value I get what looks like a rasterized image (I think). Specifically, a gradient is applied. For example, here's the result of domquant[#, 256]
:
However, if I leave the value as n = 24
or some other smaller number, I get a nice image like this which has discrete boundaries between each value of n
, and is actually what I am trying to achieve:
So, why is 24 the magic number beyond which the blur effect takes place? How can I get an image with nice discrete colors using a higher value of n
?
In response to Szabolcs, if I remove the ImageResolution
and ImageSize
options, I get this image:
Not what I'm looking for. I want to create an image like the second one above, where each of 256 colors is represented discretely, and is of arbitrary size.
In response to Simon Woods, if I add Resampling -> "Nearest"
to Export
, I ge this image with n=256
, again blurry:
Thanks to everyone who commented, the following comment from SimonWoods helped me understand. Here's the final (working) code and the resulting (quite beautiful) image.
basepath = "~"
SetDirectory[basepath]
jpgpath = FileNameJoin[{basepath, "jpg"}]
pngpath = FileNameJoin[{basepath, "png"}]
domquant[path_, n_] :=
Image[{List @@@
DominantColors[Image[ColorQuantize[Import[path], n]], n]}]
(*Convert each jpg in path to its 256-color quantized sample*)
Scan[(
img = domquant[#, 256];
img = ImageResize[img, {8152, 512}, Resampling -> "Nearest"];
Print[#, " ", img];
Export[
FileNameJoin[{pngpath, StringJoin[FileBaseName[#], ".png"]}],
img, "PNG"]) &, {FileNames["*.jpg", {jpgpath}][[1]]}]
ImageResolution -> 300, ImageSize -> {8192, 512}
trigger resampling. Don't use these settings. If you do need to resample the image, do it explicitly usingImageResize
, then export the resized image at 1-to-1 pixel size. Also, don't export such a quantized image to JPEG. The lossy compression will introduce colours that you did not originally put in the image. Use PNG instead. $\endgroup$Automatic
setting for theResampling
option inImageResize
uses nearest neighbour only if both image dimensions are <=24, and one of the interpolating methods for images larger than that. So the OP will need to specifyResampling->"Nearest"
to get the desired result. $\endgroup$ImageResize
, not forExport
. The idea is you remove the options fromExport
and useimg = ImageResize[img, {8152,512}, Resampling -> "Nearest"]
to change the image size. $\endgroup$