SlideShare a Scribd company logo
1 of 10
Download to read offline
Below are questions that use the following image class:
import assert from "assert";
import { exec } from "child_process";
import fs from "fs";
import os from "os";
import path from "path";
import tmp from "tmp";
import { PNG } from "pngjs";
const IMAGES_FOLDER = path.resolve(process.cwd(), "images");
const IMAGE_GALLERY = fs.readdirSync(IMAGES_FOLDER).map(p =>
path.join(IMAGES_FOLDER, p));
type ImageName = "art" | "bike" | "car" | "dog" | "food" | "landscape" | "pencils" | "pottery" |
"tomato";
function assertSupportedType(filePath: string) {
assert(filePath.endsWith("png"), "Image must end in `.png`.");
}
const CHANNEL_NAMES = ["red", "green", "blue"];
function assertValidColor(color: Color) {
assert(color.length === 3);
CHANNEL_NAMES.forEach((channel, i) => {
assert(Number.isInteger(color[i]), `The ${channel} channel of the color must be an integer.`);
assert(0 <= color[i], `The ${channel} channel of the color must be at least 0.`);
assert(color[i] <= 255, `The ${channel} channel of the color must be at most 255.`);
});
}
function assertValidWidthAndHeight(width: number, height: number) {
assert(Number.isInteger(width), "Image width must be an integer.");
assert(Number.isInteger(height), "Image height must be an integer.");
assert(width > 0, "Image width must be greater than 0.");
assert(height > 0, "Image height must be greater than 0.");
assert(width < 5000, "Image width must be less than 5000.");
assert(height < 5000, "Image height must be less than 5000.");
}
export type Color = number[];
export const COLORS = {
WHITE: [255, 255, 255],
BLACK: [0, 0, 0],
RED: [255, 0, 0],
GREEN: [0, 255, 0],
BLUE: [0, 0, 255],
AQUA: [0, 255, 255],
YELLOW: [255, 255, 0],
MAGENTA: [255, 0, 255],
};
export class Image {
/**
* Loads an image from the preselected gallery of images into memory as an `Image` object.
* If no name is given, this function selects one at random.
* @param name The name of the image from the gallery
* @returns An image in the gallery as an Image object.
*/
static loadImageFromGallery(name?: ImageName): Image {
return name
? Image.loadImageFromFile(path.resolve(IMAGES_FOLDER, name + ".png"))
: Image.loadImageFromFile(IMAGE_GALLERY[Math.floor(Math.random() *
IMAGE_GALLERY.length)]);
}
/**
* Loads an image from the file system into memory as an `Image` object.
* @param image Path to a PNG, JPG, JPEG file
* @returns The file represented as an `Image` object.
*/
static loadImageFromFile(filePath: string): Image {
assertSupportedType(filePath);
if (!fs.existsSync(filePath)) {
throw new Error(`Unable to locate file: `${filePath}``);
}
fs.accessSync(filePath, fs.constants.R_OK);
const png = PNG.sync.read(fs.readFileSync(filePath));
return new Image(png.width, png.height, Uint8ClampedArray.from(png.data));
}
/**
* Creates a new image and sets each pixel to a default color.
* @param width The width of the image
* @param height The height of the image
* @param fillColor The color to set each pixel as
*/
static create(width: number, height: number, fillColor: Color): Image {
assertValidWidthAndHeight(width, height);
assertValidColor(fillColor);
return new Image(
width,
height,
Uint8ClampedArray.from(
{
length: width * height * 4,
},
(_, i) => (i % 4 < 3 ? fillColor[i % 4] : 255)
)
);
}
public readonly width: number;
public readonly height: number;
private readonly data: Uint8ClampedArray;
private readonly rowSize: number;
/**
* Constructs a new `Image` object. Use `Image.create` to generate an actual image
* @param width The images width
* @param height The images height
* @param data The pixel data of the image
*/
constructor(width: number, height: number, data: Uint8ClampedArray) {
assertValidWidthAndHeight(width, height);
this.width = width;
this.height = height;
this.data = data;
this.rowSize = this.width * 4;
}
/**
* Returns the color of the pixel at the specified location.
* @param x The horizontal coordinate from the origin (top, left)
* @param y The vertical coordinate from the origin (top, left)
* @returns The color of the pixel at (x, y)
*/
getPixel(x: number, y: number): Color {
this.assertCoordinatesInBounds(x, y);
const offset = this.getOffset(x, y);
return [this.data[offset], this.data[offset + 1], this.data[offset + 2]];
}
/**
* Updates the color of a pixel in the image.
* @param x The horizontal coordinate of the pixel
* @param y The vertical coordinate of the pixel
* @param color The new color of the pixel
*/
setPixel(x: number, y: number, color: Color): void {
assertValidColor(color);
this.assertCoordinatesInBounds(x, y);
const offset = this.getOffset(x, y);
this.data[offset] = color[0];
this.data[offset + 1] = color[1];
this.data[offset + 2] = color[2];
}
/**
* Create a copy of the current state of the image.
*/
copy(): Image {
return new Image(this.width, this.height, Uint8ClampedArray.from(this.data));
}
/**
* Write the current state of the image to the file system.
* All images are saved under the current working directory (cwd) under the path
`./images_out/*.png`.
* @param fileName The name of the image
*/
save(fileName: string): void {
assert.match(
fileName,
/^(?!.{256,})(?!(aux|clock$|con|nul|prn|com[1-9]|lpt[1-9])(?:$|.))[^ ][ .w-
$()+=[];#@~,&amp;']+[^. ]$/i,
"Invalid file name."
);
const root = process.cwd();
const images_out = path.resolve(root, "images_out");
if (!fs.existsSync(images_out)) {
fs.mkdirSync(images_out);
}
this.saveToPath(path.resolve(images_out, fileName + ".png"));
}
show(): void {
const temp = tmp.fileSync({
postfix: ".png",
});
this.saveToPath(temp.name);
if (os.platform() === "darwin") {
// macOS
exec(`open ${temp.name}`);
} else {
exec(`code --reuse-window ${temp.name}`);
}
}
saveToPath(filePath: string): void {
const png = new PNG({
width: this.width,
height: this.height,
});
png.data = Buffer.from(this.data.buffer);
fs.writeFileSync(filePath, PNG.sync.write(png));
}
pixels(): Color[] {
const pixels = [];
for (let x = 0; x < this.width; x++) {
for (let y = 0; y < this.height; y++) {
pixels.push(this.getPixel(x, y));
}
}
return pixels;
}
coordinates() {
const coords = [];
for (let x = 0; x < this.width; x++) {
for (let y = 0; y < this.height; y++) {
coords.push([x, y]);
}
}
return coords;
}
assertCoordinatesInBounds(x: number, y: number) {
assert(Number.isInteger(x), "x coordinate must be an integer.");
assert(Number.isInteger(y), "y coordinate must be an integer.");
assert(x >= 0, "x coordinate must be non-negative.");
assert(x < this.width, "x coordinate must be smaller than the width.");
assert(y >= 0, "y coordinate must be non-negative.");
assert(y < this.height, "y coordinate must be smaller than the height.");
}
private getOffset(x: number, y: number): number {
return y * this.rowSize + x * 4;
}
}
1.A. Write a function called lineBlur3p:
The function should modify the image, only for any pixels having y-coordinate equal to lineNo.
The new value of each color channel is computed as a weighted sum of the original color value
in the pixel and in its neighbor(s) on that line. The weight for any neighbor is 1/3, and the weight
for the original pixel is (1 - sum of neighbor weights). It should work on every pixel in each line
including edges.
Truncate the final sum to a whole number to get the final color channel. Avoid code duplication.
See "Weighted average" on Wikipedia for more details.
1.B. Write a function called lineBlur5p:
export function lineBlur5p(img: Image, lineNo: number): void {
// TODO
}
The function should modify the image, only for any pixels having y-coordinate equal to lineNo.
The new value of each color channel is computed as a weighted sum of the original color value
in the pixel and in all other pixels on that line which are at distance up to 2. The weight for any
such pixel is 1/5, nd the weight for the original pixel is (1 - sum of other pixel weights. Avoid
code duplication (think about the commonalities between this and lineBlur3p). Use the same
truncating process as lineBlur3p. Keep in mind this uses two pixel neighbors on the left, and two
pixel neighbors on the right of the pixel it is applied to in the line. Despite this, it should work on
every pixel in the line, including edge pixels, and pixels that do not have access to a full 5 pixels
to find the average.
Could you show me the completed version of these two functions using a helper function to
reduce code repitition?

More Related Content

Similar to Below are questions that use the following image class- import assert.pdf

I have to understand this code and i have to explain the each line of.pdf
I have to understand this code and i have to explain the each line of.pdfI have to understand this code and i have to explain the each line of.pdf
I have to understand this code and i have to explain the each line of.pdf
shreeaadithyaacellso
 
could you draw uml diagram for this code from PIL import Image, Im.pdf
could you draw uml diagram for this code from PIL import Image, Im.pdfcould you draw uml diagram for this code from PIL import Image, Im.pdf
could you draw uml diagram for this code from PIL import Image, Im.pdf
murtuzadahadwala3
 
import java.awt.Color; import java.awt.Dimension; import.pdf
import java.awt.Color; import java.awt.Dimension; import.pdfimport java.awt.Color; import java.awt.Dimension; import.pdf
import java.awt.Color; import java.awt.Dimension; import.pdf
maheshkumar12354
 
openFrameworks 007 - graphics
openFrameworks 007 - graphicsopenFrameworks 007 - graphics
openFrameworks 007 - graphics
roxlu
 
I wanted to change the cloudsrectangles into an actuall image it do.pdf
I wanted to change the cloudsrectangles into an actuall image it do.pdfI wanted to change the cloudsrectangles into an actuall image it do.pdf
I wanted to change the cloudsrectangles into an actuall image it do.pdf
feelinggifts
 

Similar to Below are questions that use the following image class- import assert.pdf (20)

ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
I have to understand this code and i have to explain the each line of.pdf
I have to understand this code and i have to explain the each line of.pdfI have to understand this code and i have to explain the each line of.pdf
I have to understand this code and i have to explain the each line of.pdf
 
Scmad Chapter07
Scmad Chapter07Scmad Chapter07
Scmad Chapter07
 
Introduction to Go for Java Programmers
Introduction to Go for Java ProgrammersIntroduction to Go for Java Programmers
Introduction to Go for Java Programmers
 
could you draw uml diagram for this code from PIL import Image, Im.pdf
could you draw uml diagram for this code from PIL import Image, Im.pdfcould you draw uml diagram for this code from PIL import Image, Im.pdf
could you draw uml diagram for this code from PIL import Image, Im.pdf
 
import java.awt.Color; import java.awt.Dimension; import.pdf
import java.awt.Color; import java.awt.Dimension; import.pdfimport java.awt.Color; import java.awt.Dimension; import.pdf
import java.awt.Color; import java.awt.Dimension; import.pdf
 
Program imageviewer
Program imageviewerProgram imageviewer
Program imageviewer
 
Procedural Art
Procedural ArtProcedural Art
Procedural Art
 
Processing and Processing.js
Processing and Processing.jsProcessing and Processing.js
Processing and Processing.js
 
Applet life cycle
Applet life cycleApplet life cycle
Applet life cycle
 
Java oops features
Java oops featuresJava oops features
Java oops features
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)
 
Actionscript 3 - Session 4 Core Concept
Actionscript 3 - Session 4 Core ConceptActionscript 3 - Session 4 Core Concept
Actionscript 3 - Session 4 Core Concept
 
openFrameworks 007 - graphics
openFrameworks 007 - graphicsopenFrameworks 007 - graphics
openFrameworks 007 - graphics
 
I wanted to change the cloudsrectangles into an actuall image it do.pdf
I wanted to change the cloudsrectangles into an actuall image it do.pdfI wanted to change the cloudsrectangles into an actuall image it do.pdf
I wanted to change the cloudsrectangles into an actuall image it do.pdf
 
Histogram dan Segmentasi
Histogram dan SegmentasiHistogram dan Segmentasi
Histogram dan Segmentasi
 
Histogram dan Segmentasi 2
Histogram dan Segmentasi 2Histogram dan Segmentasi 2
Histogram dan Segmentasi 2
 
HTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGLHTML5 game dev with three.js - HexGL
HTML5 game dev with three.js - HexGL
 
ch03g-graphics.ppt
ch03g-graphics.pptch03g-graphics.ppt
ch03g-graphics.ppt
 
Write a program that reads a graph from a file and determines whether.docx
 Write a program that reads a graph from a file and determines whether.docx Write a program that reads a graph from a file and determines whether.docx
Write a program that reads a graph from a file and determines whether.docx
 

More from rdzire2014

Below I have 2 microservices that compile very well- I need help inte.pdf
Below I have 2 microservices that compile very well-  I need help inte.pdfBelow I have 2 microservices that compile very well-  I need help inte.pdf
Below I have 2 microservices that compile very well- I need help inte.pdf
rdzire2014
 
Being able to connect to the Internet is crucial for Canada's northern.pdf
Being able to connect to the Internet is crucial for Canada's northern.pdfBeing able to connect to the Internet is crucial for Canada's northern.pdf
Being able to connect to the Internet is crucial for Canada's northern.pdf
rdzire2014
 

More from rdzire2014 (20)

Below is a pedigree for a family where several members (labeled in bla (1).pdf
Below is a pedigree for a family where several members (labeled in bla (1).pdfBelow is a pedigree for a family where several members (labeled in bla (1).pdf
Below is a pedigree for a family where several members (labeled in bla (1).pdf
 
Below is a llst of balances for S- Jones- a sole treder- for the year.pdf
Below is a llst of balances for S- Jones- a sole treder- for the year.pdfBelow is a llst of balances for S- Jones- a sole treder- for the year.pdf
Below is a llst of balances for S- Jones- a sole treder- for the year.pdf
 
Below are two very simple profiles of volcanoes (A - a shield volcano-.pdf
Below are two very simple profiles of volcanoes (A - a shield volcano-.pdfBelow are two very simple profiles of volcanoes (A - a shield volcano-.pdf
Below are two very simple profiles of volcanoes (A - a shield volcano-.pdf
 
Below I have 2 microservices that compile very well- I need help inte.pdf
Below I have 2 microservices that compile very well-  I need help inte.pdfBelow I have 2 microservices that compile very well-  I need help inte.pdf
Below I have 2 microservices that compile very well- I need help inte.pdf
 
Below are a few descriptions of various components of the lymphatic sy.pdf
Below are a few descriptions of various components of the lymphatic sy.pdfBelow are a few descriptions of various components of the lymphatic sy.pdf
Below are a few descriptions of various components of the lymphatic sy.pdf
 
Below are images taken at different time points of a cell undergoing m.pdf
Below are images taken at different time points of a cell undergoing m.pdfBelow are images taken at different time points of a cell undergoing m.pdf
Below are images taken at different time points of a cell undergoing m.pdf
 
Below are 4 water-balance diagrams for different areas of the world- L.pdf
Below are 4 water-balance diagrams for different areas of the world- L.pdfBelow are 4 water-balance diagrams for different areas of the world- L.pdf
Below are 4 water-balance diagrams for different areas of the world- L.pdf
 
Being able to connect to the Internet is crucial for Canada's northern.pdf
Being able to connect to the Internet is crucial for Canada's northern.pdfBeing able to connect to the Internet is crucial for Canada's northern.pdf
Being able to connect to the Internet is crucial for Canada's northern.pdf
 
Below are data for a hypothetical country that produces three goods- r.pdf
Below are data for a hypothetical country that produces three goods- r.pdfBelow are data for a hypothetical country that produces three goods- r.pdf
Below are data for a hypothetical country that produces three goods- r.pdf
 
Beginning in the year 2018 - the net asset classifications temporarily.pdf
Beginning in the year 2018 - the net asset classifications temporarily.pdfBeginning in the year 2018 - the net asset classifications temporarily.pdf
Beginning in the year 2018 - the net asset classifications temporarily.pdf
 
Before we prepare our sample for Transmission Electron Microscopy (TEM.pdf
Before we prepare our sample for Transmission Electron Microscopy (TEM.pdfBefore we prepare our sample for Transmission Electron Microscopy (TEM.pdf
Before we prepare our sample for Transmission Electron Microscopy (TEM.pdf
 
Before we can perform the task of subtotal- what needs to be done firs.pdf
Before we can perform the task of subtotal- what needs to be done firs.pdfBefore we can perform the task of subtotal- what needs to be done firs.pdf
Before we can perform the task of subtotal- what needs to be done firs.pdf
 
Bees are haplodiploid- meaning that females are diploid and males are.pdf
Bees are haplodiploid- meaning that females are diploid and males are.pdfBees are haplodiploid- meaning that females are diploid and males are.pdf
Bees are haplodiploid- meaning that females are diploid and males are.pdf
 
bee probuced by Tactory l is ostetive n0oct1 Mhiser.pdf
bee probuced by Tactory l is ostetive n0oct1 Mhiser.pdfbee probuced by Tactory l is ostetive n0oct1 Mhiser.pdf
bee probuced by Tactory l is ostetive n0oct1 Mhiser.pdf
 
Because of their great versatility- bacteria may obtain compounds esse.pdf
Because of their great versatility- bacteria may obtain compounds esse.pdfBecause of their great versatility- bacteria may obtain compounds esse.pdf
Because of their great versatility- bacteria may obtain compounds esse.pdf
 
Because conflicts of interest increase asymmetric information problems.pdf
Because conflicts of interest increase asymmetric information problems.pdfBecause conflicts of interest increase asymmetric information problems.pdf
Because conflicts of interest increase asymmetric information problems.pdf
 
BE10-11 (LO 4) In its recent annual report- Campbell Soup Company repo.pdf
BE10-11 (LO 4) In its recent annual report- Campbell Soup Company repo.pdfBE10-11 (LO 4) In its recent annual report- Campbell Soup Company repo.pdf
BE10-11 (LO 4) In its recent annual report- Campbell Soup Company repo.pdf
 
Biotechnology Microbial Solutions- 1- Describe current examples in bio.pdf
Biotechnology Microbial Solutions- 1- Describe current examples in bio.pdfBiotechnology Microbial Solutions- 1- Describe current examples in bio.pdf
Biotechnology Microbial Solutions- 1- Describe current examples in bio.pdf
 
Be sure to show work for 4-6- One way that astronomers detect exopla.pdf
Be sure to show work for 4-6-   One way that astronomers detect exopla.pdfBe sure to show work for 4-6-   One way that astronomers detect exopla.pdf
Be sure to show work for 4-6- One way that astronomers detect exopla.pdf
 
Be able to quickly describe and - or diagram the net flow of water (in.pdf
Be able to quickly describe and - or diagram the net flow of water (in.pdfBe able to quickly describe and - or diagram the net flow of water (in.pdf
Be able to quickly describe and - or diagram the net flow of water (in.pdf
 

Recently uploaded

Spellings Wk 4 and Wk 5 for Grade 4 at CAPS
Spellings Wk 4 and Wk 5 for Grade 4 at CAPSSpellings Wk 4 and Wk 5 for Grade 4 at CAPS
Spellings Wk 4 and Wk 5 for Grade 4 at CAPS
AnaAcapella
 

Recently uploaded (20)

AIM of Education-Teachers Training-2024.ppt
AIM of Education-Teachers Training-2024.pptAIM of Education-Teachers Training-2024.ppt
AIM of Education-Teachers Training-2024.ppt
 
How to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptxHow to setup Pycharm environment for Odoo 17.pptx
How to setup Pycharm environment for Odoo 17.pptx
 
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
 
Graduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - EnglishGraduate Outcomes Presentation Slides - English
Graduate Outcomes Presentation Slides - English
 
Food safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdfFood safety_Challenges food safety laboratories_.pdf
Food safety_Challenges food safety laboratories_.pdf
 
FICTIONAL SALESMAN/SALESMAN SNSW 2024.pdf
FICTIONAL SALESMAN/SALESMAN SNSW 2024.pdfFICTIONAL SALESMAN/SALESMAN SNSW 2024.pdf
FICTIONAL SALESMAN/SALESMAN SNSW 2024.pdf
 
SOC 101 Demonstration of Learning Presentation
SOC 101 Demonstration of Learning PresentationSOC 101 Demonstration of Learning Presentation
SOC 101 Demonstration of Learning Presentation
 
Wellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptxWellbeing inclusion and digital dystopias.pptx
Wellbeing inclusion and digital dystopias.pptx
 
Google Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptxGoogle Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptx
 
How to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POSHow to Manage Global Discount in Odoo 17 POS
How to Manage Global Discount in Odoo 17 POS
 
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptxHMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
 
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
Sensory_Experience_and_Emotional_Resonance_in_Gabriel_Okaras_The_Piano_and_Th...
 
Python Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxPython Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docx
 
How to Manage Call for Tendor in Odoo 17
How to Manage Call for Tendor in Odoo 17How to Manage Call for Tendor in Odoo 17
How to Manage Call for Tendor in Odoo 17
 
Single or Multiple melodic lines structure
Single or Multiple melodic lines structureSingle or Multiple melodic lines structure
Single or Multiple melodic lines structure
 
This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.This PowerPoint helps students to consider the concept of infinity.
This PowerPoint helps students to consider the concept of infinity.
 
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptxOn_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
 
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdfUnit 3 Emotional Intelligence and Spiritual Intelligence.pdf
Unit 3 Emotional Intelligence and Spiritual Intelligence.pdf
 
Spellings Wk 4 and Wk 5 for Grade 4 at CAPS
Spellings Wk 4 and Wk 5 for Grade 4 at CAPSSpellings Wk 4 and Wk 5 for Grade 4 at CAPS
Spellings Wk 4 and Wk 5 for Grade 4 at CAPS
 
OSCM Unit 2_Operations Processes & Systems
OSCM Unit 2_Operations Processes & SystemsOSCM Unit 2_Operations Processes & Systems
OSCM Unit 2_Operations Processes & Systems
 

Below are questions that use the following image class- import assert.pdf

  • 1. Below are questions that use the following image class: import assert from "assert"; import { exec } from "child_process"; import fs from "fs"; import os from "os"; import path from "path"; import tmp from "tmp"; import { PNG } from "pngjs"; const IMAGES_FOLDER = path.resolve(process.cwd(), "images"); const IMAGE_GALLERY = fs.readdirSync(IMAGES_FOLDER).map(p => path.join(IMAGES_FOLDER, p)); type ImageName = "art" | "bike" | "car" | "dog" | "food" | "landscape" | "pencils" | "pottery" | "tomato"; function assertSupportedType(filePath: string) { assert(filePath.endsWith("png"), "Image must end in `.png`."); } const CHANNEL_NAMES = ["red", "green", "blue"]; function assertValidColor(color: Color) { assert(color.length === 3); CHANNEL_NAMES.forEach((channel, i) => { assert(Number.isInteger(color[i]), `The ${channel} channel of the color must be an integer.`); assert(0 <= color[i], `The ${channel} channel of the color must be at least 0.`); assert(color[i] <= 255, `The ${channel} channel of the color must be at most 255.`); });
  • 2. } function assertValidWidthAndHeight(width: number, height: number) { assert(Number.isInteger(width), "Image width must be an integer."); assert(Number.isInteger(height), "Image height must be an integer."); assert(width > 0, "Image width must be greater than 0."); assert(height > 0, "Image height must be greater than 0."); assert(width < 5000, "Image width must be less than 5000."); assert(height < 5000, "Image height must be less than 5000."); } export type Color = number[]; export const COLORS = { WHITE: [255, 255, 255], BLACK: [0, 0, 0], RED: [255, 0, 0], GREEN: [0, 255, 0], BLUE: [0, 0, 255], AQUA: [0, 255, 255], YELLOW: [255, 255, 0], MAGENTA: [255, 0, 255], }; export class Image { /** * Loads an image from the preselected gallery of images into memory as an `Image` object.
  • 3. * If no name is given, this function selects one at random. * @param name The name of the image from the gallery * @returns An image in the gallery as an Image object. */ static loadImageFromGallery(name?: ImageName): Image { return name ? Image.loadImageFromFile(path.resolve(IMAGES_FOLDER, name + ".png")) : Image.loadImageFromFile(IMAGE_GALLERY[Math.floor(Math.random() * IMAGE_GALLERY.length)]); } /** * Loads an image from the file system into memory as an `Image` object. * @param image Path to a PNG, JPG, JPEG file * @returns The file represented as an `Image` object. */ static loadImageFromFile(filePath: string): Image { assertSupportedType(filePath); if (!fs.existsSync(filePath)) { throw new Error(`Unable to locate file: `${filePath}``); } fs.accessSync(filePath, fs.constants.R_OK); const png = PNG.sync.read(fs.readFileSync(filePath)); return new Image(png.width, png.height, Uint8ClampedArray.from(png.data)); }
  • 4. /** * Creates a new image and sets each pixel to a default color. * @param width The width of the image * @param height The height of the image * @param fillColor The color to set each pixel as */ static create(width: number, height: number, fillColor: Color): Image { assertValidWidthAndHeight(width, height); assertValidColor(fillColor); return new Image( width, height, Uint8ClampedArray.from( { length: width * height * 4, }, (_, i) => (i % 4 < 3 ? fillColor[i % 4] : 255) ) ); } public readonly width: number; public readonly height: number; private readonly data: Uint8ClampedArray;
  • 5. private readonly rowSize: number; /** * Constructs a new `Image` object. Use `Image.create` to generate an actual image * @param width The images width * @param height The images height * @param data The pixel data of the image */ constructor(width: number, height: number, data: Uint8ClampedArray) { assertValidWidthAndHeight(width, height); this.width = width; this.height = height; this.data = data; this.rowSize = this.width * 4; } /** * Returns the color of the pixel at the specified location. * @param x The horizontal coordinate from the origin (top, left) * @param y The vertical coordinate from the origin (top, left) * @returns The color of the pixel at (x, y) */ getPixel(x: number, y: number): Color { this.assertCoordinatesInBounds(x, y); const offset = this.getOffset(x, y);
  • 6. return [this.data[offset], this.data[offset + 1], this.data[offset + 2]]; } /** * Updates the color of a pixel in the image. * @param x The horizontal coordinate of the pixel * @param y The vertical coordinate of the pixel * @param color The new color of the pixel */ setPixel(x: number, y: number, color: Color): void { assertValidColor(color); this.assertCoordinatesInBounds(x, y); const offset = this.getOffset(x, y); this.data[offset] = color[0]; this.data[offset + 1] = color[1]; this.data[offset + 2] = color[2]; } /** * Create a copy of the current state of the image. */ copy(): Image { return new Image(this.width, this.height, Uint8ClampedArray.from(this.data)); } /**
  • 7. * Write the current state of the image to the file system. * All images are saved under the current working directory (cwd) under the path `./images_out/*.png`. * @param fileName The name of the image */ save(fileName: string): void { assert.match( fileName, /^(?!.{256,})(?!(aux|clock$|con|nul|prn|com[1-9]|lpt[1-9])(?:$|.))[^ ][ .w- $()+=[];#@~,&amp;']+[^. ]$/i, "Invalid file name." ); const root = process.cwd(); const images_out = path.resolve(root, "images_out"); if (!fs.existsSync(images_out)) { fs.mkdirSync(images_out); } this.saveToPath(path.resolve(images_out, fileName + ".png")); } show(): void { const temp = tmp.fileSync({ postfix: ".png", }); this.saveToPath(temp.name);
  • 8. if (os.platform() === "darwin") { // macOS exec(`open ${temp.name}`); } else { exec(`code --reuse-window ${temp.name}`); } } saveToPath(filePath: string): void { const png = new PNG({ width: this.width, height: this.height, }); png.data = Buffer.from(this.data.buffer); fs.writeFileSync(filePath, PNG.sync.write(png)); } pixels(): Color[] { const pixels = []; for (let x = 0; x < this.width; x++) { for (let y = 0; y < this.height; y++) { pixels.push(this.getPixel(x, y)); } } return pixels;
  • 9. } coordinates() { const coords = []; for (let x = 0; x < this.width; x++) { for (let y = 0; y < this.height; y++) { coords.push([x, y]); } } return coords; } assertCoordinatesInBounds(x: number, y: number) { assert(Number.isInteger(x), "x coordinate must be an integer."); assert(Number.isInteger(y), "y coordinate must be an integer."); assert(x >= 0, "x coordinate must be non-negative."); assert(x < this.width, "x coordinate must be smaller than the width."); assert(y >= 0, "y coordinate must be non-negative."); assert(y < this.height, "y coordinate must be smaller than the height."); } private getOffset(x: number, y: number): number { return y * this.rowSize + x * 4; } } 1.A. Write a function called lineBlur3p:
  • 10. The function should modify the image, only for any pixels having y-coordinate equal to lineNo. The new value of each color channel is computed as a weighted sum of the original color value in the pixel and in its neighbor(s) on that line. The weight for any neighbor is 1/3, and the weight for the original pixel is (1 - sum of neighbor weights). It should work on every pixel in each line including edges. Truncate the final sum to a whole number to get the final color channel. Avoid code duplication. See "Weighted average" on Wikipedia for more details. 1.B. Write a function called lineBlur5p: export function lineBlur5p(img: Image, lineNo: number): void { // TODO } The function should modify the image, only for any pixels having y-coordinate equal to lineNo. The new value of each color channel is computed as a weighted sum of the original color value in the pixel and in all other pixels on that line which are at distance up to 2. The weight for any such pixel is 1/5, nd the weight for the original pixel is (1 - sum of other pixel weights. Avoid code duplication (think about the commonalities between this and lineBlur3p). Use the same truncating process as lineBlur3p. Keep in mind this uses two pixel neighbors on the left, and two pixel neighbors on the right of the pixel it is applied to in the line. Despite this, it should work on every pixel in the line, including edge pixels, and pixels that do not have access to a full 5 pixels to find the average. Could you show me the completed version of these two functions using a helper function to reduce code repitition?