画像をレインボー化する


23

この課題は、次のようなきれいな写真を作成するために画像の色相を徐々に変化させることです。

大きな星空オリジナル

チャレンジ

選択した任意の一般的な画像ファイル形式で、2つの非負の整数と画像を取り込むプログラムまたは関数を記述します(画像または生の画像データへのパスを取得できます)。

最初の整数をサイクル、2番目の整数をオフセットと呼びます。

また、浮動小数点ステップを360回のサイクルを画像の面積で割った値、またはとして定義しますstep = 360 * cycles / (image width * image height)

画像内の各ピクセルPについて、一度に1行ずつ、左から右、上から下に(つまり、ピクセルが文字の場合は読み取り順に)、次の操作を行います。

  1. 増加色相Pをすることによってオフセット度(必要であれば0に360からの周りにループ)。

  2. 次に、オフセットstepずつ増やします。

結果の画像を一般的な画像ファイル形式で保存、表示、または生で出力します。

この手順は、増分的製造、画像内の全画素の色相を増加させるサイクルを周囲に完全なループを色相虹によって最初に色相をオフセットすることにより開始、オフセット

場合サイクルが 1であり、オフセット上記星空の画像のように、0であり、画素の上部と下部の行は実質的にない色相シフトを有しているが、間にフルカラーのサイクルがあります。

詳細

  • サイクルは任意の負でない整数にすることができますが、オフセットは0から359までであると仮定できます。

  • サイクルが0の場合、ステップも0でなければならないため、画像内のすべてのピクセルの色相は正確にオフセットされます。(この場合、オフセットが0の場合、画像はまったく変更されません。)

  • サイクルオフセットは、必要に応じて(つまりの1.0代わりに1)floatとして入力されると想定できます。(整数である必要はまったくないことを理解しています。これにより、チャレンジが簡単になります。)

  • 「色相」は、HSL / HSVカラーモデルで一般的なRGBカラースペースバージョンを指します

元の:

川

サイクル= 1、オフセット= 0:

河川出力1

サイクル= 1、オフセット= 180:

河川出力2

元の:

球体

サイクル= 2、オフセット= 60:

球出力

元の:

日没
ArtOfCodeに感謝します。)

サイクル= 1、オフセット= 120:

サンセット出力

元の:

ドアノブ
ドアノブに感謝します。)

サイクル= 1、オフセット= 0:

ドアノブ出力1

サイクル= 4、オフセット= 0:

ドアノブ出力2

サイクル= 200、オフセット= 0:

ドアノブ出力3

サイクル= 30000、オフセット= 0:

ドアノブ出力4

(これらの画像は、画像を圧縮するため、ピクセル完璧ではない場合があります。)

得点

バイト単位の最短コードが優先されます。Tiebreakerは、より高い投票数の回答です。

クールな見た目のテスト画像を投稿すると、ブラウニーポイントが増えます。


6
これは、ドアノブがポットを吸っているように見えます。
デンカー

戻り値が「または出力raw」に含まれるので、整数の配列を想定していますか?
-Marv

2
@Marvいいえ。画像の生バイト(選択した共通形式、たとえばppm)を直接stdoutにパイプで送ることができることを意味します。
カルビンの趣味

2
出力は例と同一でなければなりませんか?画像が少し異なります。
DJMcMayhem

1
@DrGreenEg​​gsandHamDJ視覚的に違いがわからない場合は、おそらく大丈夫です。ピクセルの完全性は必要ありません(とにかくimgurが画像を損失的に圧縮した可能性があります)。
カルビンの趣味

回答:


8

Pyth、86バイト、フルプログラム

=N.tE7=Z*6*.n0cEl.n'zMmhtS[0255ss*VG.>+Lc-1.tH1 3[.tH1Kc.tH0@3 2_K)d)3.wmmgk~-NZd'z

Pythには組み込みの色空間変換がありません-これが本当の取引です。

stdinで次の形式で入力を受け取ります。

input_filename.png
offset
cycles

出力イメージはに書き込まれo.pngます。


これは、カラーキューブをその対角線の周りに回転させ、範囲外の値をクランプすることで機能します。

場合aによって回転角度であり、r, g, b入力色で、我々は新しい色を計算するr', g', b'ことで:

o = cos(a), i = sin(a) / sqrt(3)
n = (1 - o) / 3
m = [n + o, n - i, n + i]
clamp(c) = max(0, min(255, c))
r' = clamp(r*m[0] + g*m[1] + b*m[2])
g' = clamp(r*m[2] + g*m[0] + b*m[1])
b' = clamp(r*m[1] + g*m[2] + b*m[0])

6

Python、379バイト

from PIL.Image import*
from colorsys import*
def f(H,c,I):
 i=open(I);x,y=i.size;S=1.*c/(x*y);r,g,b=i.split();R=[];G=[];B=[]
 for x,y,z in zip(r.getdata(),g.getdata(),b.getdata()):
  e=255.;h,s,v=rgb_to_hsv(x/e,y/e,z/e);t=hsv_to_rgb(h+H,s,v);H=H+S%1.;x,y,z=[int(x*e)for x in t];R.append(x);G.append(y);B.append(z)
 p=Image.putdata;p(r,R);p(g,G);p(b,B);return merge('RGB',(r,g,b))

これは、.jpg入力としてへのパスを取ります。png画像を読み込むr,g,b=i.split();ようr,g,b=i.split()[:3];に変更できますが、pngでは機能しません。

以下にいくつかの画像を示します。

元の:

ここに画像の説明を入力してください

オフセット:0、サイクル:4

ここに画像の説明を入力してください

元の:

ここに画像の説明を入力してください

オフセット0、1サイクル:

ここに画像の説明を入力してください

元の:

ここに画像の説明を入力してください

オフセット0、2.5サイクル:

ここに画像の説明を入力してください


6

Java(フルプログラム)、491 488バイト(@Geobitsに感謝)

import java.awt.*;import java.io.*;import static javax.imageio.ImageIO.*;class Q{public static void main(String[]v)throws Exception{File f=new File(v[2]);java.awt.image.BufferedImage b=read(f);for(int i=0,j,h=b.getHeight(),w=b.getWidth();i<h;i++)for(j=0;j<w;){Color c=new Color(b.getRGB(j,i));float[]a=new float[3];c.RGBtoHSB(c.getRed(),c.getGreen(),c.getBlue(),a);b.setRGB(j++,i,c.HSBtoRGB((a[0]+Float.valueOf(v[1])/360+(i*w+j)*Float.valueOf(v[0])/w/h)%1,a[1],a[2]));}write(b,"png",f);}}

非ゴルフ

import java.awt.*;
import java.io.*;

import static javax.imageio.ImageIO.*;

class A79200 {
    public static void main(String[] v) throws Exception {
        File file = new File(v[2]);
        java.awt.image.BufferedImage image = read(file);
        for (int i = 0, j, height = image.getHeight(), width = image.getWidth(); i < height; i++)
            for (j = 0; j < width; ) {
                Color color = new Color(image.getRGB(j, i));
                float[] arr = new float[3];
                color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), arr);
                image.setRGB(j++, i, color.HSBtoRGB((arr[0] + Float.valueOf(v[1]) / 360 + (i * width + j) * Float.valueOf(v[0]) / width / height) % 1, arr[1], arr[2]));
            }
        write(image, "png", file);
    }
}

説明

  • 使用法:とても簡単です。でコンパイルしjava -c Q.javaます。で実行しjava Q <cycles> <offset> <imagepath>ます。既存の画像を上書きしますので、注意してください。

  • 私は最初はメソッドのみのソリューションを作成するつもりでしたが、それらのインポートを処理する方法をよく知りませんでしたので、私は完全なに行くと思いました、これはおそらく勝ちません:^)

結果:

Image 1: 1 cycle, 0 offset

1

Image 1: 1 cycle, 180 offset

2

Image 2: 2 cycles, 60 offset

3

Image 3: 1 cycle, 120 offset

4

Image 4: 1 cycle, 0 offset

5

Image 4: 4 cycles, 0 offset

6

Image 4: 200 cycles, 0 offset

7

Bonus: The Starry Night, 1 cycle, 0 offset

ここに画像の説明を入力してください


1
後で参照できるように、メソッドのみの回答のインポートは、通常と同じように実行できます。それらをメソッド本体の外側に置き、バイトをカウントするだけです。クラスを1回だけ必要とする場合は、インポートする代わりにクラスを完全修飾して、場合によっては数バイトを節約することもできます。
ジオビット

また、java.io.Fileではなくインポートする理由はありますjava.io.*か?
ジオビット

知っていただきありがとうございます。第二に、いや、理由はありません。いい視点ね。
マーヴ

なぜimport ** static**だけでなくimport
ソロモンウッコ

1
だから私が呼び出すことができるよということImageIO::readと、ImageIO::write先頭に追加することなく、ImageIO.これは(9つのバイトが追加されますstatic .*)が、(16セーブImageIO.2回)。
マーヴ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.