彩虹化图像


23

这个挑战是关于逐渐改变图像的色调来制作漂亮的图片,如下所示:

大星夜原始

挑战

编写一个程序或函数,该程序或函数使用两个非负整数和一个您选择的任何常见图像文件格式的图像(您可以采用指向图像或原始图像数据的路径)。

我们将第一个整数称为循环,将第二个整数称为offset

我们还将浮点步长定义为360倍周期除以图像面积,即step = 360 * cycles / (image width * image height)

对于图像中的每个像素P,从左到右,从上到下一次移动一行(即,如果像素是字母,则按读取顺序),请执行以下操作:

  1. 增加色调P偏移度(如果必要的话,从360循环周围为0)。

  2. 然后增加抵消步骤

以任何常见图像文件格式保存,显示或原始输出结果图像。

此过程递增地增加了图像中的所有像素的色调,使得循环满环周围的色调的彩虹,通过最初偏移色调通过开始偏移

周期为1且偏移为0时,如上面的“星夜”图片所示,像素的顶行和底行几乎没有色相偏移,但在这之间有一个完整的颜色周期。

细节

  • 循环可以是任何非负整数,但是您可以假定偏移量是从0到359(含)。

  • cycles为0时,图像中的每个像素的色相都会偏移精确的偏移量,因为step也必须为0。(在这种情况下,如果offset为0,则图像根本不会改变。)

  • 如果需要,您可以假设周期偏移量输入为浮点数(即1.0代替1)。(我意识到它们根本不需要是整数,这只是使挑战变得更加简单。)

  • “色相”是指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

(由于imgur压缩它们,这些图像可能不是像素完美的。)

计分

以字节为单位的最短代码获胜。决胜局是最高投票的答案。

发表自己很酷的测试图像的答案将从我身上获得更多的布朗尼分数。


6
看起来门把手正在抽些锅子。
Denker

我假设一个整数数组,因为返回值将包含在“或输出原始”中?
Marv

2
@Marv号。我的意思是图像的原始字节(以您选择的常用格式,例如ppm)可以直接通过管道传递到stdout。
加尔文的爱好

2
输出是否必须与您的示例相同?我得到的图像略有不同。
DJMcMayhem

1
@DrGreenEg​​gsandHamDJ如果您无法从视觉上分辨出差异,那么可能就可以了。不需要像素完美(反正imgur可能有损地压缩了我的图像)。
加尔文的爱好

Answers:


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将以a的路径作为输入。它不会与巴工作,但你可以改变r,g,b=i.split();r,g,b=i.split()[:3];加载PNG图像。

以下是一些图片:

原版的:

在此处输入图片说明

偏移量:0,周期:4

在此处输入图片说明

原版的:

在此处输入图片说明

偏移0、1个周期:

在此处输入图片说明

原版的:

在此处输入图片说明

偏移0、2.5个周期:

在此处输入图片说明


6

爪哇(全程序),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
为了将来参考,您可以像通常一样导入仅方法的答案。只需将它们放在方法主体之外并计算字节数即可。如果只需要一次,也可以完全限定类而不是导入它们,以在某些情况下节省一些字节。
Geobits's

此外,您是否有理由要导入java.io.File而不是java.io.*
Geobits's

谢谢,很高兴知道。第二,没有,没有理由。好点子。
Marv

为什么import ** static**,而不仅仅是import
所罗门·乌科

1
这样我就可以调用ImageIO::readImageIO::write无需ImageIO.添加前缀:这增加了9个字节(static .*),但保存了16个(ImageIO.两次)。
Marv
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.