Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as RX from "https://cdn.skypack.dev/rambdax"
- import * as Path from "https://deno.land/std@0.116.0/path/mod.ts"
- import * as Canvas from "https://deno.land/x/canvas/mod.ts"
- import {ImageData} from "https://deno.land/x/canvas@v1.3.0/src/types.ts"
- // Just run: deno run index.ts --allow-read --allow-write "C:/ANY_DIR/Screenshot.jpg"
- // Assemble: deno compile index.ts --allow-read --allow-write
- interface PathInfo { root: string; dir: string; base: string; ext: string; name: string; path: string; }
- interface State { state: string; detail: string; }
- interface SizeMap { [key: string]: number[][]; }
- const NUM_OF_CHANNEL = 4
- const SIZE_MAP: SizeMap = {
- "1600,900": [[1395, 876], [1560, 900]],
- "1920,1080": [[1670, 1052], [1863, 1080]],
- }
- const rename: (oldName: string) => string =
- (oldName: string) => `${oldName}_erased`
- const exists: (path: string) => Promise<boolean> =
- RX.tryCatchAsync(RX.pipeAsync(Deno.stat, RX.T), RX.F)
- function fillWithFirstLine(image: ImageData) {
- const {width, height, data} = image
- for (let y = 0; y < height; y++) {
- for (let x = 0; x < width; x++) {
- const point1 = (y * width + x) * NUM_OF_CHANNEL
- const point2 = x * NUM_OF_CHANNEL
- data[point1 + 0] = data[point2 + 0]
- data[point1 + 1] = data[point2 + 1]
- data[point1 + 2] = data[point2 + 2]
- data[point1 + 3] = data[point2 + 3]
- }
- }
- return image
- }
- async function fillImageIdArea(arg: string): Promise<Uint8Array | null> {
- const image: Canvas.Image = await Canvas.loadImage(arg)
- const [imageW, imageH] = [image.width(), image.height()]
- const sizeSignature = [imageW, imageH].toString()
- if (!(sizeSignature in SIZE_MAP)) return null
- const [[fromX, fromY], [toX, toY]] = SIZE_MAP[sizeSignature]
- console.debug(`Filling ID area from: { x: ${fromX} y: ${fromY} } to: { x: ${toX} y:${toY} }`)
- // load image on canvas
- const canvas: Canvas.EmulatedCanvas2D = Canvas.createCanvas(imageW, imageH)
- const context: Canvas.CanvasRenderingContext2D = canvas.getContext("2d")
- context.drawImage(image, 0, 0)
- // fill ID area
- const [idAreaW, idAreaH] = [toX - fromX, toY - fromY]
- const oldIdAreaImage: ImageData = context.getImageData(fromX, fromY, idAreaW, idAreaH)
- const newIdAreaImage: ImageData = fillWithFirstLine(oldIdAreaImage)
- context.putImageData(newIdAreaImage, fromX, fromY)
- return canvas.toBuffer()
- }
- async function procPath(pathInfo: PathInfo): Promise<State> {
- if (!(await exists(pathInfo.path))) {
- throw new Error(`Cannot find the specified file: ${pathInfo.path}`)
- }
- console.info(`Processing file ${pathInfo.base} ...`)
- const buffer = await fillImageIdArea(pathInfo.path)
- if (buffer === null) {
- throw new Error("Failed to process the image.")
- }
- const newFileName = `${rename(pathInfo.name)}${pathInfo.ext}`
- const newPath = Path.resolve(pathInfo.dir, newFileName)
- await Deno.writeFile(newPath, buffer)
- console.debug(`Write file to ${newFileName}`)
- return {state: "success", detail: newPath}
- }
- // parse paths
- const pathInfos = Deno.args
- .filter(arg => !arg.startsWith("-"))
- .map(path => ({path, ...Path.parse(path)}))
- // proc files async
- for (const pathInfo of pathInfos) {
- await procPath(pathInfo)
- }
- // keep console screen
- prompt("Please enter input...")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement