[Question]
  [
This challenge is about gradually shifting hues in an image to make pretty pictures like this:
[![big Starry Night](https://i.stack.imgur.com/hDcQr.jpg)](https://i.stack.imgur.com/hDcQr.jpg)
([original](https://i.stack.imgur.com/XFKAg.jpg))
# Challenge
Write a program or function that takes in two non-negative integers and an image in any common image file format of your choosing (you can take a path to the image or the raw image data).
We'll call the first integer the **cycles** and the second integer the **offset**.
We'll also define floating-point **step** as 360 times **cycles** divided by the area of the image, or `step = 360 * cycles / (image width * image height)`.
For each pixel **P** in the image, moving one row at a time, left-to-right, top-to-bottom (i.e. in reading order if the pixels were letters), do the following:
1. Increase the [hue](https://en.wikipedia.org/wiki/Hue) of **P** by **offset** degrees (looping around from 360 to 0 if necessary).
2. Then increase **offset** by **step**.
Save, display, or output raw the resulting image in any common image file format.
This procedure incrementally increases the hue of all the pixels in the image, making **cycles** full loops around the [hue rainbow](https://en.wikipedia.org/wiki/Hue#/media/File:HueScale.svg), starting by initially offsetting the hue by **offset**.
When **cycles** is 1 and **offset** is 0, as in the Starry Night image above, the top and bottom rows of pixels have practically no hue shift but in between there's a full color cycle.
# Details
* **Cycles** can be any non-negative integer but you may assume that **offset** is from 0 to 359 inclusive.
* When **cycles** is 0, every pixel in the image will have its hue shifted by exactly **offset** since **step** must be 0 too. (In this case if **offset** is 0 then the image doesn't change at all.)
* You may assume **cycles** and **offset** are input as floats if desired (i.e. `1.0` instead of `1`). (I realize they needn't be integers at all, it just makes the challenge simpler.)
* "Hue" refers to the RGB color space version, common in [HSL/HSV color models](https://en.wikipedia.org/wiki/HSL_and_HSV).
# Examples
Original:
[![river](https://i.stack.imgur.com/8sEvg.png)](https://i.stack.imgur.com/8sEvg.png)
Cycles = 1, offset = 0:
[![river output 1](https://i.stack.imgur.com/83Fky.png)](https://i.stack.imgur.com/83Fky.png)
Cycles = 1, offset = 180:
[![river output 2](https://i.stack.imgur.com/W4GZA.png)](https://i.stack.imgur.com/W4GZA.png)
Original:
[![spheres](https://i.stack.imgur.com/BgfFX.png)](https://i.stack.imgur.com/BgfFX.png)
Cycles = 2, offset = 60:
[![spheres output](https://i.stack.imgur.com/XffYB.png)](https://i.stack.imgur.com/XffYB.png)
Original:
[![sunset](https://i.stack.imgur.com/Ulokx.png)](https://i.stack.imgur.com/Ulokx.png)  
(Thanks [ArtOfCode](https://hardwarerecs.stackexchange.com/users/8/artofcode).)
Cycles = 1, offset = 120:
[![sunset output](https://i.stack.imgur.com/rjKNP.png)](https://i.stack.imgur.com/rjKNP.png)
Original:
[![doorknob](https://i.stack.imgur.com/shFHM.png)](https://i.stack.imgur.com/shFHM.png)  
(Thanks [Doorknob](https://codegolf.stackexchange.com/users/3808/doorknob).)
Cycles = 1, offset = 0:
[![doorknob output 1](https://i.stack.imgur.com/hjji7.png)](https://i.stack.imgur.com/hjji7.png)
Cycles = 4, offset = 0:
[![doorknob output 2](https://i.stack.imgur.com/Jok8J.png)](https://i.stack.imgur.com/Jok8J.png)
Cycles = 200, offset = 0:
[![doorknob output 3](https://i.stack.imgur.com/LILtv.png)](https://i.stack.imgur.com/LILtv.png)
Cycles = 30000, offset = 0:
[![doorknob output 4](https://i.stack.imgur.com/GrMEY.png)](https://i.stack.imgur.com/GrMEY.png)
(These images may not be pixel perfect due to imgur compressing them.)
# Scoring
The shortest code in bytes wins. Tiebreaker is higher voted answer.
Answers that post their own cool looking test images will get more brownie points from me.
  
[Answer]
# Pyth, 86 bytes, full program
```
=N.tE7=Z*6*.n0cEl.n'zMmhtS[0255ss*VG.>+Lc-1.tH1 3[.tH1Kc.tH0@3 2_K)d)3.wmmgk~-NZd'z
```
Pyth doesn't have built-in color space conversions - this is the real deal.
Takes input in the following format on stdin:
```
input_filename.png
offset
cycles
```
The output image is written to `o.png`.
---
This works by rotating the color cube around its diagonal, and then clamping any values outside of the range.
If `a` is the angle to rotate by, and `r, g, b` is the input color, we calculate the new color `r', g', b'` by:
```
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])
```
[Answer]
# Python, 379 bytes
```
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))
```
This takes a path to a `.jpg` as input. It will not work with png, although you can change `r,g,b=i.split();` to `r,g,b=i.split()[:3];` to load a png image.
Here are some images:
Original:
[![enter image description here](https://i.stack.imgur.com/McvcF.jpg)](https://i.stack.imgur.com/McvcF.jpg)
Offset: 0, Cycles: 4
[![enter image description here](https://i.stack.imgur.com/Mj2iB.jpg)](https://i.stack.imgur.com/Mj2iB.jpg)
Original:
[![enter image description here](https://i.stack.imgur.com/oHQyc.jpg)](https://i.stack.imgur.com/oHQyc.jpg)
Offset 0, 1 cycle:
[![enter image description here](https://i.stack.imgur.com/40vyj.jpg)](https://i.stack.imgur.com/40vyj.jpg)
Original:
[![enter image description here](https://i.stack.imgur.com/qrxVX.jpg)](https://i.stack.imgur.com/qrxVX.jpg)
Offset 0, 2.5 cycles:
[![enter image description here](https://i.stack.imgur.com/85Ph7.jpg)](https://i.stack.imgur.com/85Ph7.jpg)
[Answer]
# Java (Full program), 491 488 bytes (Thanks @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);}}
```
### Ungolfed
```
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);
    }
}
```
### Explanation
* Usage: Pretty straightforward. Compile with `java -c Q.java`. Run with `java Q <cycles> <offset> <imagepath>`. Will override the existing image, so be careful.
* I was gonna make a method only solution at first but I didn't quite know how to handle imports on those, so I figured I'd go full [java](/questions/tagged/java "show questions tagged 'java'"), this is *probably* not going to win anyways :^)
### Results:
`Image 1: 1 cycle, 0 offset`
[![1](https://i.stack.imgur.com/bX5fV.png)](https://i.stack.imgur.com/bX5fV.png)
`Image 1: 1 cycle, 180 offset`
[![2](https://i.stack.imgur.com/Gngiq.png)](https://i.stack.imgur.com/Gngiq.png)
`Image 2: 2 cycles, 60 offset`
[![3](https://i.stack.imgur.com/9FpUb.png)](https://i.stack.imgur.com/9FpUb.png)
`Image 3: 1 cycle, 120 offset`
[![4](https://i.stack.imgur.com/NitRj.png)](https://i.stack.imgur.com/NitRj.png)
`Image 4: 1 cycle, 0 offset`
[![5](https://i.stack.imgur.com/3jSi1.png)](https://i.stack.imgur.com/3jSi1.png)
`Image 4: 4 cycles, 0 offset`
[![6](https://i.stack.imgur.com/YhrG8.png)](https://i.stack.imgur.com/YhrG8.png)
`Image 4: 200 cycles, 0 offset`
[![7](https://i.stack.imgur.com/QCuAd.png)](https://i.stack.imgur.com/QCuAd.png)
`Bonus: The Starry Night, 1 cycle, 0 offset`
[![enter image description here](https://i.stack.imgur.com/Bxsta.jpg)](https://i.stack.imgur.com/Bxsta.jpg)
]