Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| steve-wang-generating-photos-with-code [2023/06/07 19:52] – created steve.wang | steve-wang-generating-photos-with-code [2023/06/07 22:56] (current) – renick | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== Generating Photos With Code ====== | ====== Generating Photos With Code ====== | ||
| - | By: [[steve-wang|Steve Wang]] | + | By [[steve-wang|Steve Wang]] |
| + | |||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | {{: | ||
| + | |||
| + | <code javascript> | ||
| + | // import the JIMP library | ||
| + | |||
| + | var Jimp = require(" | ||
| + | var fs = require(' | ||
| + | |||
| + | let classPaths = [ | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ] | ||
| + | |||
| + | |||
| + | let mangoPaths = [ | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ' | ||
| + | ] | ||
| + | |||
| + | //generated by chatgpt | ||
| + | function getFilePaths(directoryPath) { | ||
| + | const files = fs.readdirSync(directoryPath); | ||
| + | const filePaths = []; | ||
| + | files.forEach(file => { | ||
| + | const filePath = `${directoryPath}/ | ||
| + | const stat = fs.statSync(filePath); | ||
| + | if (stat.isFile()) { | ||
| + | filePaths.push(filePath); | ||
| + | } else if (stat.isDirectory()) { | ||
| + | const subDirectoryPath = `${directoryPath}/ | ||
| + | const subDirectoryFilePaths = getFilePaths(subDirectoryPath); | ||
| + | filePaths.push(...subDirectoryFilePaths); | ||
| + | } | ||
| + | }); | ||
| + | return filePaths; | ||
| + | } | ||
| + | |||
| + | // | ||
| + | |||
| + | function roundOff (number, | ||
| + | let roundedNumber=number.toFixed(decimalPlaces); | ||
| + | return JSON.parse(roundedNumber)} | ||
| + | |||
| + | function randomRange(min, | ||
| + | if (decimalPlaces==undefined){decimalPlaces=0} | ||
| + | |||
| + | } | ||
| + | |||
| + | function safeSplice(inputArray, | ||
| + | let array1 = inputArray.slice(0, | ||
| + | if (replaceWith!=undefined){ | ||
| + | array1.push(replaceWith)} | ||
| + | let array2 = inputArray.slice(indexToRemove + amountToRemove, | ||
| + | return array1.concat(array2) | ||
| + | } | ||
| + | |||
| + | // knuth shuffle from https:// | ||
| + | |||
| + | function shuffle(array) { | ||
| + | var currentIndex = array.length, | ||
| + | // 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], | ||
| + | } | ||
| + | return array; | ||
| + | } | ||
| + | |||
| + | async function allPossibleImages (foreground, | ||
| + | console.time(' | ||
| + | let foregroundPaths = getFilePaths(foreground) | ||
| + | let backgroundPaths = getFilePaths(background) | ||
| + | let foregroundImgs = foregroundPaths.map(path => Jimp.read(path)); | ||
| + | let backgroundImgs = backgroundPaths.map(path => Jimp.read(path)); | ||
| + | makeVariationDirectories(foregroundPaths, | ||
| + | console.log(' | ||
| + | //await matchAllForegroundToAllBackgrounds(foregroundImgs, | ||
| + | await matchAllForegroundToAllBackgroundsWithRotation(foregroundImgs, | ||
| + | console.timeEnd(' | ||
| + | |||
| + | } | ||
| + | |||
| + | function makeVariationDirectories (foreground, | ||
| + | fs.mkdirSync(' | ||
| + | foreground.forEach(x => { | ||
| + | fs.mkdirSync(' | ||
| + | fs.copyFileSync(x, | ||
| + | }) | ||
| + | } | ||
| + | |||
| + | function getFileNameFromPath (path){ | ||
| + | return path.slice(path.lastIndexOf('/' | ||
| + | } | ||
| + | |||
| + | function matchAllForegroundToAllBackgrounds (foregroundImgs, | ||
| + | return Promise.all(foregroundImgs).then ((forePicture) => { | ||
| + | return Promise.all(backgroundImgs).then ((backPicture) => { | ||
| + | forePicture.forEach((x, | ||
| + | backPicture.forEach((b, | ||
| + | console.log(n, | ||
| + | x | ||
| + | .composite(b, | ||
| + | .quality(97) // set JPEG quality | ||
| + | .write(' | ||
| + | }) | ||
| + | }) | ||
| + | }) | ||
| + | resolve(true) | ||
| + | }) | ||
| + | } | ||
| + | |||
| + | function matchAllForegroundToAllBackgroundsWithRotation (foregroundImgs, | ||
| + | return Promise.all(foregroundImgs).then ((forePicture) => { | ||
| + | return Promise.all(backgroundImgs).then ((backPicture) => { | ||
| + | forePicture.forEach((x, | ||
| + | let currentForeground = getFileNameFromPath(foregroundPaths[n]) | ||
| + | backPicture.forEach((b, | ||
| + | let currentBackground = getFileNameFromPath(backgroundPaths[i]) | ||
| + | for (let r = 0; r < 4; r++) { | ||
| + | console.log(' | ||
| + | console.log(n, | ||
| + | x | ||
| + | .rotate(r * 90) | ||
| + | .composite(b, | ||
| + | .quality(97) // set JPEG quality | ||
| + | .write(' | ||
| + | } | ||
| + | }) | ||
| + | }) | ||
| + | }) | ||
| + | resolve(true) | ||
| + | }) | ||
| + | } | ||
| + | |||
| + | allPossibleImages(' | ||
| + | |||
| + | endTime = new Date () | ||
| + | |||
| + | // | ||
| + | |||
| + | //only ingram and arduino uploaded to wiki: | ||
| + | |||
| + | filePath = ' | ||
| + | |||
| + | filePath = ' | ||
| + | |||
| + | files = fs.readdirSync(filePath); | ||
| + | files.forEach( (file,i) =>{ | ||
| + | if (file[0]!=' | ||
| + | fs.renameSync(filePath + '/' | ||
| + | } | ||
| + | }) | ||
| + | wikiString = '' | ||
| + | files = fs.readdirSync(filePath); | ||
| + | files.forEach(x => { | ||
| + | wikiString += ' | ||
| + | }) | ||
| + | fs.writeFileSync(' | ||
| + | |||
| + | let other = allFilePathsInDirectory(' | ||
| + | |||
| + | async function resizeAllImages (pathArray){ | ||
| + | let jimpData = pathArray.map(path => Jimp.read(path)); | ||
| + | let readData; | ||
| + | await Promise.all(jimpData).then ((pictures) => {readData = pictures}) | ||
| + | readData.forEach((x, | ||
| + | if (x.bitmap.width > 400 && x.bitmap.height > 400){ | ||
| + | x.crop(0, 0, 400, 400).quality(98).write(pathArray[i]) | ||
| + | } | ||
| + | else{ | ||
| + | x.resize(400, | ||
| + | } | ||
| + | }) | ||
| + | } | ||
| + | |||
| + | resizeAllImages(classPaths) | ||
| + | |||
| + | function combinePhotos (pathArray, outputPath){ | ||
| + | let jimpData = pathArray.map(path => Jimp.read(path)); | ||
| + | Promise.all(jimpData).then ((picture) => { | ||
| + | return picture[2] | ||
| + | .composite(picture[0], | ||
| + | .composite(picture[1], | ||
| + | | ||
| + | | ||
| + | .quality(97) // set JPEG quality | ||
| + | .write(outputPath); | ||
| + | | ||
| + | } | ||
| + | |||
| + | let twoMangoes = [mangoPaths[0], | ||
| + | combinePhotos(mangoPaths," | ||
| + | |||
| + | //Get all files: https:// | ||
| + | |||
| + | fs.readdir(' | ||
| + | console.log(files) | ||
| + | files.forEach( (file,i) =>{ | ||
| + | if (file[0]!=' | ||
| + | fs.renameSync('/ | ||
| + | } | ||
| + | }) | ||
| + | }) | ||
| + | |||
| + | console.time(' | ||
| + | total = 0 | ||
| + | for (let i = 0; i < 10000000; i++) { | ||
| + | total += Math.random() | ||
| + | } | ||
| + | console.log(' | ||
| + | console.timeEnd(' | ||
| + | |||
| + | //no multi: 113.997ms | ||
| + | </ | ||
| - | {{: | ||
| - | {{: | ||
| - | {{: | ||
| - | {{: | ||
| - | {{: | ||
| - | {{: | ||
| - | {{: | ||
| - | {{: | ||
| - | {{: | ||
| - | {{: | ||