Skip to content

Instantly share code, notes, and snippets.

@gnardini
Created May 7, 2023 00:18
Show Gist options
  • Save gnardini/457120d75e1babc82113c77f5b9d5694 to your computer and use it in GitHub Desktop.
Save gnardini/457120d75e1babc82113c77f5b9d5694 to your computer and use it in GitHub Desktop.
Create an infographic from a template
import axios from "axios";
import fs from "fs";
import sharp from "sharp";
import text2png from "text2png";
import {
getLatestVersion,
updateLatestVersion,
} from "../src/staticData/version";
import { championImage, fetchChampions } from "../src/utils/champions";
async function createLeaderboardImage() {
await updateLatestVersion();
const templatePath = "templates/leaderboard.jpg";
const outputPath = `output/leaderboard-${new Date()
.toISOString()
.slice(0, 10)}.jpg`;
const allChampions = await fetchChampions(getLatestVersion());
const champions = allChampions
.sort((c1, c2) => c2.winrate - c1.winrate)
.slice(0, 10)
.map((champion) => ({
name: champion.name,
imageUrl: championImage(champion.key),
winrate: champion.winrate,
}));
const templateImage = sharp(templatePath);
let compositeArray = [];
const patchBuffer = text2png(getLatestVersion(), {
font: "52px Montserrat-SemiBold",
color: "#7FA7CF",
localFontPath: "templates/fonts/Montserrat-SemiBold.ttf",
localFontName: "Montserrat-SemiBold",
});
compositeArray.push({ input: patchBuffer, top: 300, left: 320 });
for (let i = 0; i < champions.length; i++) {
const champion = champions[i];
const response = await axios.get(champion.imageUrl, {
responseType: "arraybuffer",
});
const imageBuffer = Buffer.from(response.data, "binary");
const roundedCorners = Buffer.from(
`<svg><rect x="0" y="0" width="256" height="256" rx="24" ry="24"/></svg>`
);
const resizedImageBuffer = await sharp(imageBuffer)
.resize(288, 288)
.extract({ left: 16, top: 16, width: 256, height: 256 })
.composite([{ input: roundedCorners, blend: "dest-in" }])
.toBuffer();
const x = i < 5 ? 480 : 1660;
const y = 605 + (i % 5) * 374;
compositeArray.push({ input: resizedImageBuffer, top: y, left: x });
const nameBuffer = text2png(champion.name, {
font: "52px Montserrat-Bold",
color: "#B7B7C9",
localFontPath: "templates/fonts/Montserrat-Bold.ttf",
localFontName: "Montserrat-Bold",
});
compositeArray.push({ input: nameBuffer, top: y + 35, left: x + 300 });
const winrateBuffer = text2png(`${champion.winrate} %`, {
font: "66px Montserrat-SemiBold",
color: "#8AF6CF",
localFontPath: "templates/fonts/Montserrat-SemiBold.ttf",
localFontName: "Montserrat-SemiBold",
});
compositeArray.push({ input: winrateBuffer, top: y + 140, left: x + 300 });
const winrateTextBuffer = text2png("WIN RATE", {
font: "30px Montserrat-Medium",
color: "#B7B7C9",
localFontPath: "templates/fonts/Montserrat-Medium.ttf",
localFontName: "Montserrat-Medium",
});
compositeArray.push({
input: winrateTextBuffer,
top: y + 210,
left: x + 300,
});
}
const resultImage = await templateImage.composite(compositeArray).toBuffer();
fs.writeFileSync(outputPath, resultImage);
}
createLeaderboardImage()
.then(() => console.log("Leaderboard image created successfully"))
.catch((error) => console.error("Error creating leaderboard image:", error));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment