====== Generating Photos with Code 程式生成照片 ======
By [[yiler-huang| Yiler Huang]]
===== First round =====
{{:yiler-jimp-photo-1.jpeg?400|}}
{{:yiler-jimp-photo-2.jpeg?400|}}
{{:yiler-jimp-photo-3.jpeg?400|}}
{{:yiler-jimp-photo-4.jpeg?400|}}
{{:yiler-jimp-photo-5.jpeg?400|}}
{{:yiler-jimp-photo-6.jpeg?400|}}
{{:yiler-jimp-photo-7.jpeg?400|}}
{{:yiler-jimp-photo-8.jpeg?400|}}
{{:yiler-jimp-photo-9.jpeg?400|}}
{{:yiler-jimp-photo-10.jpeg?400|}}
{{:yiler-jimp-photo-11.jpeg?400|}}
{{:yiler-jimp-photo-12.jpeg?400|}}
===== Second round =====
{{:yiler-jimp-second-round-1.jpg?400|}} {{:yiler-jimp-second-round-2.jpg?400|}} {{:yiler-jimp-second-round-3.jpg?400|}} {{:yiler-jimp-second-round-4.jpg?400|}} {{:yiler-jimp-second-round-5.jpg?400|}}
===== Third round =====
==== First program ====
{{:yiler-jimp-round-3-1.jpg?400|}} {{:yiler-jimp-round-3-2.jpg?400|}} {{:yiler-jimp-round-3-3.jpg?400|}} {{:yiler-jimp-round-3-4.jpg?400|}} {{:yiler-jimp-round-3-5.jpg?400|}} {{:yiler-jimp-round-3-6.jpg?400|}} {{:yiler-jimp-round-3-7.jpg?400|}} {{:yiler-jimp-round-3-8.jpg?400|}} {{:yiler-jimp-round-3-9.jpg?400|}} {{:yiler-jimp-round-3-10.jpg?400|}}
==== Second program ====
{{:yiler-jimp-round-3-11.jpg?400|}} {{:yiler-jimp-round-3-12.jpg?400|}} {{:yiler-jimp-round-3-13.jpg?400|}} {{:yiler-jimp-round-3-14.jpg?400|}} {{:yiler-jimp-round-3-15.jpg?400|}} {{:yiler-jimp-round-3-16.jpg?400|}} {{:yiler-jimp-round-3-17.jpg?400|}} {{:yiler-jimp-round-3-18.jpg?400|}} {{:yiler-jimp-round-3-19.jpg?400|}}
// import the JIMP library
const Jimp = require("jimp");
const fs = require('fs');
// knuth shuffle from https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
//shuffle
function shuffle(array) {
var currentIndex = array.length,
randomIndex;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]
];
}
return array;
}
//randomRange
function randomRange(min, max) {
return min + ((max - min) * Math.random())
}
//pickFromArray
function pickFromArray(array) {
return array[Math.floor(Math.random() * array.length)];
}
//from https://jeremyresearch.medium.com/node-js-count-the-numbers-of-files-in-a-directory-9562dec64a45
// set the path data in an array
let pathArray = [
"pics/input1.jpg",
"pics/input2.jpg",
"pics/input3.jpg",
"pics/input4.jpg",
"pics/input5.jpg",
"pics/input6.jpg",
"pics/input7.jpg",
"pics/input8.jpg",
];
function trueOrFalse() {
let output = Math.random() < 0.5 ? true : false;
return output
}
// use map to read the path data and produce JIMP Promises
let newPA = shuffle(pathArray).slice(0, 3)
let jimpData = newPA.map(path => Jimp.read(path));
// through Promise.all, get the data from the Promises and process it through the methods provided by JIMP
// the data processing will proceed in parallel, just as it does in Hydra
for (let i = 0; i < 50; i++) {
Promise.all(jimpData).then((pictures) => {
return pictures[0]
.grayscale()
//composite argument1: shiftX, argument2: shiftY
.composite(pictures[1].color([{
apply: "tint",
params: [randomRange(0, 30)]
}]).mirror(trueOrFalse(), trueOrFalse()), 0, 0, {
mode: Jimp.BLEND_LIGHTEN,
opacitySource: 1
})
.composite(pictures[2].grayscale().dither565().dither565(), 0,0, {
mode:Jimp.BLEND_DARKEN,
opacitySource: 0.6
})
.color([{
apply: "hue",
params: [randomRange(-360, 360)]
}])
.resize(2000, 2000)
.write(`./output-3/output-${i}.jpg`);
}).catch((err) => {
console.error(err)
})
newPA = shuffle(pathArray).slice(0, 2)
jimpData = newPA.map(path => Jimp.read(path));
}
==== Program 3 ====
{{:yiler-jimp-round-3-20.jpg?400|}} {{:yiler-jimp-round-3-21.jpg?400|}} {{:yiler-jimp-round-3-22.jpg?400|}} {{:yiler-jimp-round-3-23.jpg?400|}} {{:yiler-jimp-round-3-24.jpg?400|}} {{:yiler-jimp-round-3-25.jpg?400|}} {{:yiler-jimp-round-3-26.jpg?400|}} {{:yiler-jimp-round-3-27.jpg?400|}} {{:yiler-jimp-round-3-28.jpg?400|}} {{:yiler-jimp-round-3-29.jpg?400|}} {{:yiler-revised-photo-porfolio-3.jpg?400|}} {{:yiler-revised-photo-porfolio-2.jpg?400|}} {{:yiler-revised-photo-porfolio-1.jpg?400|}}
// import the JIMP library
const Jimp = require("jimp");
const fs = require('fs');
// knuth shuffle from https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
//shuffle
function shuffle(array) {
var currentIndex = array.length,
randomIndex;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]
];
}
return array;
}
//randomRange
function randomRange(min, max) {
return min + ((max - min) * Math.random())
}
//pickFromArray
function pickFromArray(array) {
return array[Math.floor(Math.random() * array.length)];
}
//from https://jeremyresearch.medium.com/node-js-count-the-numbers-of-files-in-a-directory-9562dec64a45
// set the path data in an array
let pathArray = [
"pics/input1.jpg",
"pics/input2.jpg",
"pics/input3.jpg",
"pics/input4.jpg",
"pics/input5.jpg",
"pics/input6.jpg",
"pics/input7.jpg",
"pics/input8.jpg",
"pics/input9.jpg",
"pics/input10.jpg",
"pics/input11.jpg",
"pics/input12.jpg",
];
function trueOrFalse() {
let output = Math.random() < 0.5 ? true : false;
return output
}
// use map to read the path data and produce JIMP Promises
let newPA = shuffle(pathArray).slice(0, 3)
let jimpData = newPA.map(path => Jimp.read(path));
// through Promise.all, get the data from the Promises and process it through the methods provided by JIMP
// the data processing will proceed in parallel, just as it does in Hydra
for (let i = 0; i < 100; i++) {
Promise.all(jimpData).then((pictures) => {
return pictures[0]
.grayscale()
//composite argument1: shiftX, argument2: shiftY
.composite(pictures[1].grayscale().invert(), 0,0, {
mode:Jimp.BLEND_DARKEN,
opacitySource: 0.8
})
.composite(pictures[2].color([{
apply: "tint",
params: [randomRange(0, 30)]
}]).mirror(trueOrFalse(), trueOrFalse()), 0, 0, {
mode: Jimp.BLEND_LIGHTEN,
opacitySource: 1
})
.color([{
apply: "hue",
params: [randomRange(-360, 360)]
}])
.resize(2000, 2000)
.write(`./output-5/output-${i}.jpg`);
}).catch((err) => {
console.error(err)
})
newPA = shuffle(pathArray).slice(0, 3)
jimpData = newPA.map(path => Jimp.read(path));
}