The task
Given an image as input, your task is to do the following:
- Resize the image so it is At least 2 times smaller, but still has the same width/height ratio by taking every second (if resized to 2x) pixel in both horizontal and vertical directions and using those in the pixel art image. Example:
a 4x4 image
[abcd
,efgh
,ijkl
,mnop]
When resized to 2x will become one of the following:
[ac [bd [eg [fh
,ik] ,jl] ,mo] ,np]
- Each RGB pixel in the newly resized image must be converted to a 3-bit color, so there are 8 different possible colors:
Red (255,0,0)
Green (0,255,0)
Blue (0,0,255)
Light Blue (0,255,255)
Magenta (255,0,255)
Yellow (255,255,0)
White (255,255,255)
Black (0,0,0)
An image of the colors:
- And output the resulting image.
Input
Your input may be:
- An image
- A path to the inputting image
Output
Can be:
- An image
- A path to the outputting image
Rules
- The inputting image will not be larger than 2048x2048 and will always be at least 256x256
- The outputting image must be at least 64x64
- When changing pixels, the original pixel must be converted to the closest (euclidean) pixel in the 3-bit scheme, no randomization
- You may hardcode how much you resize the image if you want to
- When submitting your answer, please include the following:
- Your byte-count in the title
- Your code
- An pair of images, one original of your choice and the other being the "pixel-art" from that image
- This is code-golf, so lowest byte count for each language wins.
Test cases
-
\$\begingroup\$ @Noodle9 will edit and clarify, the resizing works by taking every second (if resized to 2x) pixel from the original image. \$\endgroup\$Dion– Dion2020年04月21日 10:24:10 +00:00Commented Apr 21, 2020 at 10:24
-
1\$\begingroup\$ What is the metric used for "closest" for colors? What stops us from outputting an 1x1 image? \$\endgroup\$the default.– the default.2020年04月21日 10:27:03 +00:00Commented Apr 21, 2020 at 10:27
-
\$\begingroup\$ @mypronounismonicareinstate When i made an ungolfed version of this, I used (r//128*255,g//128*255,b//128*255) for (r,g,b) in every pixel (python). As for the size, will add in rules to output at least 64x64 image \$\endgroup\$Dion– Dion2020年04月21日 10:29:45 +00:00Commented Apr 21, 2020 at 10:29
-
\$\begingroup\$ @Noodle9 added an explanation in the post \$\endgroup\$Dion– Dion2020年04月21日 10:36:51 +00:00Commented Apr 21, 2020 at 10:36
-
3\$\begingroup\$ I will repeat @mypronounismonicareinstate : What stops us from outputting a 1x1 image since the ratio is ours to decide? \$\endgroup\$Olivier Grégoire– Olivier Grégoire2020年04月21日 10:51:08 +00:00Commented Apr 21, 2020 at 10:51
11 Answers 11
Sledgehammer, (削除) 22 (削除ここまで) 17 bytes
I noticed I'm no longer winning for some reason and made a minor IO golf
⢟⢡⡂⠴⠒⢂⢜⠧⣘⡨⡏⣻⢈⠯⣧⠼⡫
Corresponding Mathematica code: Export[".bmp",ImageAdjust[Import[#]~Downsample~2, 9!]]& . Takes input from the file with name specified in the program's arguments (for some reason these are put in a file, too), outputs to the file .bmp. There are literally built-ins for everything!
- built-in for reading arbitrary image format
- built-in for downsampling
- built-in for adjusting the contrast by \9ドル!\$
- built-in for writing all that into a file
At least it's not PixelArtify[Input[]].
Mathematica, (削除) 61 (削除ここまで) 31 bytes
ImageAdjust[#~Downsample~2,9!]&
Adjusts the contrast of the downsampled image by the factorial of nine.
-
\$\begingroup\$ I guess my answer helped you to remove Import/Export \$\endgroup\$ZaMoC– ZaMoC2020年04月21日 12:46:07 +00:00Commented Apr 21, 2020 at 12:46
-
\$\begingroup\$ I included them in the Sledgehammer code because while I could input and output a bunch of pixel values, that's not very kind, and that answer is probably winning anyway, so I could sacrifice a few bytes for that purpose. \$\endgroup\$the default.– the default.2020年04月21日 12:50:38 +00:00Commented Apr 21, 2020 at 12:50
MATL, 18 bytes
Yi2Lt3:K$)127>o2YG
The input is a string with the file name. The output is an image displayed in a window.
Input image:
Output image:
Explanation
Yi % Implicit input: filename. Read image. Gives an ×ばつ3 uint8 array
2L % Push [2 2 j] (predefined literal). When interpreted as an index,
% this means 2:2:end
t % Duplicate
3: % Push [1 2 3]
K$) % 4-input indexing. Downsamples the image by a factor of 2 in each
% dimension of the first two dimensions (vertical and horizontal),
% while keeping the three colour components
127> % Greater than 127? Gives true (1) or false (0)
o % Convert to double
2YG % Display image. For double data type this assumes range from 0 to 1
Python 3 + imageio, (削除) 68 (削除ここまで) 67 bytes
Takes the filename as input, overwrites the original file.
from imageio import*
lambda f:imwrite(f,(~imread(f)[::2,::2]>>7)-1)
imageio.imread returns a numpy 3d array of unsigned 8-bit integers corresponding to the RGB value of each pixel. array[::2, ::2] takes every other row and every other column of the array.
Because of the 8-bit data type (~array>>7)-1 is equivalent to ((255-array)//128-1)%256.
-
\$\begingroup\$ Is it me or this output is not downsampled? \$\endgroup\$the default.– the default.2020年04月21日 14:03:40 +00:00Commented Apr 21, 2020 at 14:03
-
\$\begingroup\$ @mypronounismonicareinstate I displayed a downscaled version of the original because it took up so much space, the true original would open if you click on it. I have changed this now because this will probably confuse more people. \$\endgroup\$ovs– ovs2020年04月21日 14:11:17 +00:00Commented Apr 21, 2020 at 14:11
-
\$\begingroup\$ Damn, i also used python 3 but used PIL as it's the only image library I know. Well done! \$\endgroup\$Dion– Dion2020年04月21日 18:02:36 +00:00Commented Apr 21, 2020 at 18:02
Wolfram Language (Mathematica), 69 bytes
Image[#&@@Nearest[{0,1}~Tuples~3,#]&/@#&/@ImageData@Downsample[#,2]]&
-
1\$\begingroup\$ I out-builtinned you! \$\endgroup\$the default.– the default.2020年04月21日 12:35:40 +00:00Commented Apr 21, 2020 at 12:35
-
\$\begingroup\$ @mypronounismonicareinstate yes, I forgot about downsample... \$\endgroup\$ZaMoC– ZaMoC2020年04月21日 12:42:43 +00:00Commented Apr 21, 2020 at 12:42
Java 10, (削除) 255 (削除ここまで) (削除) 254 (削除ここまで) (削除) 252 (削除ここまで) (削除) 251 (削除ここまで) 248 bytes
import java.awt.image.*;I->{int w=I.getWidth()/2,h=I.getHeight()/2,c[]={0,255,65535,65280,255<<16,16711935,16776960,-1>>>8};var r=new BufferedImage(w,h,13,new IndexColorModel(3,8,c,0,0>1,1,0));r.createGraphics().drawImage(I,0,0,w,h,null);return r;}
-2 bytes thanks to @mypronounismonicareinstate
-4 bytes thanks to @OlivierGrégoire.
Some example I/O:
enter image description here enter image description here enter image description here enter image description here
I/O as a java.awt.image.BufferedImage.
Explanation:
import java.awt.image.*; // Import for BufferedImage and IndexColorModel
I->{ // Method with BufferedImage as both parameter & return
int w=I.getWidth()/2, // Get the width/2 of the input-image
h=I.getHeight()/2, // Get the height/2 of the input-image
c[]={ // Integer-arry for the colors:
0, // 0x000000 (black)
255, // 0x0000ff (blue)
65535, // 0x00ff00 (green)
65280, // 0x00ffff (aqua)
255<<16, // 0xff0000 (red)
16711935, // 0xff00ff (magenta)
16776960, // 0xffff00 (yellow)
-1>>>8}; // 0xffffff (white)
var r=new BufferedImage(w,h,// Create the return-BufferdImage with this size, and:
13, // An indexed byte image (BufferedImage.TYPE_BYTE_INDEXED)
new IndexColorModel( // Using the following ColorModel:
3, // 3-bits
8,c, // with the 8 colors of the earlier created array
0, // without an offset index
0>1, // without alpha layers (false)
1, // without transparent colors (Transparency.OPAQUE)
0)); // using unsigned bytes as data (DataBuffer.TYPE_BYTE)
r.createGraphics() // Convert this image to a Graphics2D object
.drawImage(I, // So we can use the input-image for it
0,0, // with 0,0 as starting x,y coordinates
w,h, // the same halved width & height
null); // and no ImageObserver
return r;} // Return this created BufferedImage as result
-
\$\begingroup\$ Are the last 3 parameters of
IndexColorModelnecessary? \$\endgroup\$Olivier Grégoire– Olivier Grégoire2020年04月22日 12:39:59 +00:00Commented Apr 22, 2020 at 12:39 -
1\$\begingroup\$ Does something like
-1u>>8work for 16777215? \$\endgroup\$the default.– the default.2020年04月22日 12:40:03 +00:00Commented Apr 22, 2020 at 12:40 -
\$\begingroup\$ @OlivierGrégoire I'm afraid so. The constructors of the
IndexColorModelare limited when using anint[]for the colors. It's either(int,int,int[],int,boolean,int,int)orint,int,int[],int,int,BigInteger). It also has a constructor withbyte[], but those can't fit some of the colors, and the three separated parameters forred,green,blue, but I doubt those would save bytes considering the three loose arrays. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2020年04月22日 12:43:32 +00:00Commented Apr 22, 2020 at 12:43 -
\$\begingroup\$ @mypronounismonicareinstate Thanks, that indeed works (although it's
>>>instead ofu>>in Java). I tried to find something shorter for some of those numbers, but didn't really worked out. Thanks! \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2020年04月22日 12:44:14 +00:00Commented Apr 22, 2020 at 12:44 -
1\$\begingroup\$ Ok for the constructors, I hadn't noticed the change from byte[] to int[]. Also, same idea as @mypronounismonicareinstate:
255<<16 == 16711680. \$\endgroup\$Olivier Grégoire– Olivier Grégoire2020年04月22日 12:49:50 +00:00Commented Apr 22, 2020 at 12:49
Red, (削除) 150 (削除ここまで) 148 bytes
func[s][r: func[a][round/to a 255]i: load s forall i[i/1: as-rgba r i/1/1
r i/1/2 r i/1/3 0]view compose[base(i/size / 2)draw[scale .5 .5 image i]]]
The output is an image displayed in a window.
Figure Original
Figure x.5 Scale 0.5
Samoyed Original
Samoyed x 0.5 Scale x 0.5
-
\$\begingroup\$ That downsampled dog is pretty scary looking :p \$\endgroup\$2020年09月24日 03:55:36 +00:00Commented Sep 24, 2020 at 3:55
-
\$\begingroup\$ @RedwolfPrograms It's the first time I hear someone to call a samoyed dog "scary looking" :) It's good that you were talking about the downsampled one. I have a samoyed dog myself, not as fluffy as the one above though and still she's adorable! \$\endgroup\$Galen Ivanov– Galen Ivanov2020年09月24日 06:46:43 +00:00Commented Sep 24, 2020 at 6:46
bash + ImageMagick, (削除) 123 (削除ここまで) 50 bytes
convert "1ドル" -sample 50% +dither -posterize 2 "2ドル"
Untested, as I haven't actually installed it; I've just cribbed stuff from Stack Overflow. Edit: Saved 73 bytes thanks to @someone.
-
\$\begingroup\$ There's the
-posterizeflag that probably does the equivalent of thered,lime,blue,...thingy (I don't understand that line properly though). \$\endgroup\$the default.– the default.2020年04月21日 13:35:05 +00:00Commented Apr 21, 2020 at 13:35 -
\$\begingroup\$ @someone What that line did was to generate an image with that palette so that the input image could be converted to the same palette. \$\endgroup\$Neil– Neil2020年04月21日 14:05:20 +00:00Commented Apr 21, 2020 at 14:05
-
\$\begingroup\$ I think the double quotes are unnecessary (on this website). Mogrify instead of convert can probably save a few bytes too. \$\endgroup\$the default.– the default.2020年04月22日 01:20:20 +00:00Commented Apr 22, 2020 at 1:20
bash + netpbm, 30 bytes
pnmdepth 1|pnmscale -nomix 0.5
Takes input on stdin as a PNM file, and outputs on stdout as a PNM file.
pnmdepth 1 reduces the depth of the image on its stdin to 1, and pnmscale 0.5 reduces the size by a half in each direction. The -nomix option is required for pnmscale to choose a pixel from the starting image for each output pixel, instead of mixing adjacent input pixels into one output pixel.
-
1\$\begingroup\$ Does it parse
.5as 0.5? (I haven't tried) \$\endgroup\$the default.– the default.2020年04月22日 06:16:45 +00:00Commented Apr 22, 2020 at 6:16
Python 3 + PIL, (削除) 211 (削除ここまで) 208 bytes
from PIL import Image as I
i=I.open(input(),'r')
p=i.load()
q,g=i.size;a=q//4;c=g//4
u=I.new('RGB',(a,c))
o=u.load()
for w in range(a):
for h in range(c):o[w,h]=tuple(e//128*255 for e in p[w*4,h*4])
u.show()
Golfed the testing script I used to create the test cases for this challenge
-
1\$\begingroup\$ When you post a challenge, it's good to let a few days before you post your try, so that people can try in all the languages they want. \$\endgroup\$Olivier Grégoire– Olivier Grégoire2020年04月21日 15:21:50 +00:00Commented Apr 21, 2020 at 15:21
-
4\$\begingroup\$ @OlivierGrégoire I don't see how this answer prevents people from answering... \$\endgroup\$the default.– the default.2020年04月23日 02:49:51 +00:00Commented Apr 23, 2020 at 2:49
MATLAB, 32 bytes
@(x)(x(1:2:end,1:2:end,:)>127)*1
Both input and output are images. Output is an array storing image data, it's not specified in challenge that output image must be displayed. (to display result add 8 bytes for imshow(...) command)
The actual result and original:
input image
output image
Art credit to Janna Sophia.
Processing, 463 bytes
size(500,500);String u="";PImage p=loadImage(u);p.resize(p.width/2,p.height/2);noStroke();color[]c={#ff0000,#00ff00,#0000ff,#00ffff,#ff00ff,#ffff00,#ffffff,0};p.loadPixels();for(int i=0;i<p.width;i++){for(int j=0;j<p.height;j++){float[]d=new float[8];color x=p.get(i,j);for(int k=0;k<8;k++)d[k]=sqrt(sq(red(x)-red(c[k]))+sq(blue(x)-blue(c[k]))+sq(green(x)-green(c[k])));int b=0;for(int l=0;l<8;l++){if(d[l]<=d[b]){b=l;}}fill(c[b]);rect(i,j,1,1);}}save(u+"1.png");
Takes image location, saves pixel art as image1.png. enter image description here enter image description here Image from beeple.