C、429(定義フラグの場合は391 + 38)
i,R,G,B,q;char*c,t[99];main(r,a,b,k,z,p){scanf("%*[^ ]%d%*6s%d%[^N]%*[^R]R\n",&a,&b,t);int j=a*b,d[j],e[j];F(c=d;c<d+j;*c++=getchar());F(;i<j;e[i++]=X<<24|B/q<<16|G/q<<8|R/q,R=G=B=q=0)F(k=0;k<j;)p=d[k++],D<r&&(++q,R+=p&X,G+=p>>8&X,B+=p>>16&X);F(i=!printf("P7\nWIDTH %d\nHEIGHT %d%sNDHDR\n",a,b,t);i<j;d[i++]=e[k])F(;k=rand()%j,D>r/2;);F(c=d;q<j*4;i=(q%4-2?2:3)*c[q]/2,putchar(i>X?X:i),++q);}
入力形式:pam
ヘッダーにコメントまたは余分な空白がないファイル、STDIN経由で渡されるコンテンツ。
n
引数が必要です(何でもかまいません)。
出力形式:pam
STDOUTのファイル。
コンパイルします:
gcc -DX=255 -DF=for "-DD=z=abs(k-i),z/b+z%a" -Wl,--stack,33554432 -funsigned-char icyavatars.c -o icyavatars
-Wl,--stack,33554432
スタックサイズを増やします。これは、処理中の画像のサイズに応じて変更または削除できます(プログラムでは、ピクセル数の2倍に4を超えるスタックサイズが必要です)。
-funsigned-char
forのunsigned char
代わりにgccを使用signed char
しchar
ます。C標準ではこれらのオプションのいずれかが許可されており、gccはsigned char
デフォルトで使用するため、このオプションはここでのみ必要です。
実行するには(n = 5):
./icyavatars random argument here fourth fifth < image.pam > output.pam
注: Windowsでコンパイルする場合stdio.h
、fcntl.h
およびをio.h
含める必要がありmain()
、プログラムがテキストではなくバイナリストリームとしてSTDIN / STDOUTを読み書きするために、次のコードをstartに追加する(これはLinuxでは無関係ですが、 Windowsはテキストストリームの\r\n
代わりに使用し\n
ます)。
setmode(fileno(stdin), _O_BINARY);
setmode(fileno(stdout), _O_BINARY);
コメント版
int i,R,G,B,q;
char *c,t[99];
main(r,a,b,k,z,p){
// read all of header
// save a large chunk to t, save width to a, save height to b
scanf("%*[^ ]%d%*6s%d%[^N]%*[^R]R\n", &a, &b, t);
// create arrays for holding the pixels
int j = a * b, d[j], e[j];
// each pixel is 4 bytes, so we just read byte by byte to the int arrays
for(c = d; c < d + j; ++c)
*c=getchar();
// calculating average rgb
for(i = 0; i < j; ++i){
// check every pixel; add r/g/b values to R/G/B if manhattan distance < r-1
for(k = 0; k < j; ++k){
// pixel being checked
p = d[k];
// manhattan distance
z = abs(k - i)/b + abs(k - i)%a;
if(z < r){
// extract components and add
++q;
R += p & 255;
G += p >> 8 & 255;
B += p >> 16 & 255;
}
}
// set pixel in e (not d) to average RGB and 255 alpha
e[i]= 255<<24 | B/q<<16 | G/q<<8 | R/q;
// clear temporary variables
R = G = B = q = 0;
}
// print header
printf("P7\nWIDTH %d\nHEIGHT %d%sNDHDR\n",a,b,t);
// choose random pixels
for(i = 0; i < j; ++i){
// loop until randomly generated integer represents a pixel that is close enough
do{
k = rand() % j;
// manhattan distance
z = abs(k - i)/b + abs(k - i)%a;
}while(z > r/2);
// set d to the new pixel value
d[i] = e[k];
}
// apply blue scaling and output
for(c = d, q = 0; q < j * 4; ++q){
// 3/2 if blue component, 1 otherwise
i = (q % 4 - 2 ? 2 : 3)*c[q]/2;
// cap components at 255
putchar(i > 255 ? 255 : i);
}
}
n = 10のマーティン:
n = 20のマーティン:
n = 100のマーティン: