-
37dist/gammacorrection.html
-
BINdist/gammacorrection.png
-
BINdist/grayscale-finished.png
-
45dist/grayscale.html
-
BINdist/quantise-color-poster-finished.png
-
BINdist/quantise-grayscale-poster-finished.png
-
BINdist/quantise-hist-finished.png
-
BINdist/quantise.jpg
-
45dist/quantisecolor.html
-
45dist/quantisegrayscale.html
-
18src/03/gammacorrection.ts
-
16src/03/grayscale.ts
-
17src/03/quantisecolor.ts
-
17src/03/quantisegrayscale.ts
-
49src/03/setup-gammacorrection.ts
-
38src/03/setup-grayscale.ts
-
38src/03/setup-quantisecolor.ts
-
38src/03/setup-quantisegrayscale.ts
@ -0,0 +1,37 @@ |
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Graphische Datenverarbeitung - Color - Gamma Correction</title> |
|||
<script type="text/javascript" src="gammacorrection.bundle.js"></script> |
|||
<link rel="icon" type="image/png" href="ai-logo.png"> |
|||
</head> |
|||
|
|||
<body> |
|||
<nav class="navbar navbar-light bg-light"> |
|||
<div class="container"> |
|||
<a class="navbar-brand" href="/index.html"> |
|||
<img src="ai-logo.png" width="30" height="30" class="d-inline-block align-top" alt=""> |
|||
Graphische Datenverarbeitung |
|||
</a> |
|||
<div class="navbar-brand">Gamma Correction</div> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="container"> |
|||
<figure class="figure mx-auto d-block"> |
|||
<canvas id="result" class="figure-img mx-auto d-block" width="800" height="400"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
<div class="form-group text-left"> |
|||
<label for="gammaslider">Gamma</label> |
|||
<input class="form-control-range" type="range" id="gammaslider" min="1" max="5" step="0.1"> |
|||
</div> |
|||
Determine the color of each pixel after the gamma correction |
|||
</figcaption> |
|||
</figure> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
After Width: 800 | Height: 400 | Size: 8.4 KiB |
After Width: 512 | Height: 384 | Size: 233 KiB |
@ -0,0 +1,45 @@ |
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Graphische Datenverarbeitung - Color - XYZ</title> |
|||
<script type="text/javascript" src="grayscale.bundle.js"></script> |
|||
<link rel="icon" type="image/png" href="ai-logo.png"> |
|||
</head> |
|||
|
|||
<body> |
|||
<nav class="navbar navbar-light bg-light"> |
|||
<div class="container"> |
|||
<a class="navbar-brand" href="/index.html"> |
|||
<img src="ai-logo.png" width="30" height="30" class="d-inline-block align-top" alt=""> |
|||
Graphische Datenverarbeitung |
|||
</a> |
|||
<div class="navbar-brand">Grayscale</div> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="result" class="figure-img mx-auto d-block" width="512" height="384"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Create a grayscale version by converting the RBG values to XYZ and use the Y value. |
|||
</figcaption> |
|||
</figure> |
|||
<figure class="figure col-sm-6"> |
|||
<img class="figure-img mx-auto d-block" src="grayscale-finished.png"> |
|||
<figcaption class="figure-caption text-center">Reference image</figcaption> |
|||
</figure> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="original" class="figure-img mx-auto d-block" width="512" height="384"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Original |
|||
</figcaption> |
|||
</figure> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
After Width: 512 | Height: 384 | Size: 37 KiB |
After Width: 512 | Height: 384 | Size: 15 KiB |
After Width: 396 | Height: 396 | Size: 28 KiB |
After Width: 1024 | Height: 768 | Size: 228 KiB |
@ -0,0 +1,45 @@ |
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Graphische Datenverarbeitung - Color - XYZ</title> |
|||
<script type="text/javascript" src="quantisecolor.bundle.js"></script> |
|||
<link rel="icon" type="image/png" href="ai-logo.png"> |
|||
</head> |
|||
|
|||
<body> |
|||
<nav class="navbar navbar-light bg-light"> |
|||
<div class="container"> |
|||
<a class="navbar-brand" href="/index.html"> |
|||
<img src="ai-logo.png" width="30" height="30" class="d-inline-block align-top" alt=""> |
|||
Graphische Datenverarbeitung |
|||
</a> |
|||
<div class="navbar-brand">Posterise Color</div> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="result" class="figure-img mx-auto d-block" width="512" height="384"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Quantise the image to 4 brightness values per color channel. |
|||
</figcaption> |
|||
</figure> |
|||
<figure class="figure col-sm-6"> |
|||
<img class="figure-img mx-auto d-block" src="quantise-color-poster-finished.png"> |
|||
<figcaption class="figure-caption text-center">Reference image</figcaption> |
|||
</figure> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="original" class="figure-img mx-auto d-block" width="512" height="384"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Original |
|||
</figcaption> |
|||
</figure> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,45 @@ |
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Graphische Datenverarbeitung - Color - XYZ</title> |
|||
<script type="text/javascript" src="quantisegrayscale.bundle.js"></script> |
|||
<link rel="icon" type="image/png" href="ai-logo.png"> |
|||
</head> |
|||
|
|||
<body> |
|||
<nav class="navbar navbar-light bg-light"> |
|||
<div class="container"> |
|||
<a class="navbar-brand" href="/index.html"> |
|||
<img src="ai-logo.png" width="30" height="30" class="d-inline-block align-top" alt=""> |
|||
Graphische Datenverarbeitung |
|||
</a> |
|||
<div class="navbar-brand">Posterise Black and White</div> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="result" class="figure-img mx-auto d-block" width="512" height="384"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Quantise the image to 4 brightness values. |
|||
</figcaption> |
|||
</figure> |
|||
<figure class="figure col-sm-6"> |
|||
<img class="figure-img mx-auto d-block" src="quantise-grayscale-poster-finished.png"> |
|||
<figcaption class="figure-caption text-center">Reference image</figcaption> |
|||
</figure> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="original" class="figure-img mx-auto d-block" width="512" height="384"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Original |
|||
</figcaption> |
|||
</figure> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,18 @@ |
|||
/** |
|||
* Conducts a gamma adjustment with a given gamma value on the pixel |
|||
* (x, y). The original color information can be read from the source image. |
|||
* The adjusted color is to be saved in the dest array. |
|||
* @param {number} gamma The gamma factor to adjust the brightness |
|||
* @param {Uint8ClampedArray} source The original pixel data |
|||
* @param {Uint8ClampedArray} dest The array to save the adjusted color data to |
|||
* @param {number} x The x coordinate of the pixel to adjust |
|||
* @param {number} y The y coordinate of the pixel to adjust |
|||
* @param {number} width The width of the image in pixels |
|||
* @param {number} height The height of the image in pixels |
|||
*/ |
|||
export function gammaAdjust(gamma: number, source: Uint8ClampedArray, |
|||
dest: Uint8ClampedArray, x: number, y: number, |
|||
width: number, height: number) { |
|||
|
|||
// TODO: Perform a gamma correction with the given gamma value on the current pixel at position (x, y) in the source array, and store the result in the dest array.
|
|||
} |
@ -0,0 +1,16 @@ |
|||
/** |
|||
* Convert the color information of the pixel at (x, y) to grayscale by using the |
|||
* Y coordinate of the XYZ color space. |
|||
* |
|||
* @param x The x coordinate of the pixel to convert |
|||
* @param y The y coordinate of the pixel to convert |
|||
* @param source The source image data |
|||
* @param target The image data to save the converted color information to |
|||
* @param width The width of the canvas |
|||
* @param height The height of the canvas |
|||
*/ |
|||
export function grayscale(x: number, y: number, source: Uint8ClampedArray, target: Uint8ClampedArray, width: number, height: number) { |
|||
|
|||
// TODO: Convert the pixel at position (x, y) in the source array from RGB to XYZ.
|
|||
// TODO: Set the RGBA values in the target array according to the Y component of the source pixel in XYZ space.
|
|||
} |
@ -0,0 +1,17 @@ |
|||
/** |
|||
* Posterise the source image and save the result in the target image. |
|||
* Restrict each color channel to four equidistant values. |
|||
* |
|||
* @param x The x coordinate of the pixel to posterise |
|||
* @param y The y coordinate of the pixel to posterise |
|||
* @param source The source image data |
|||
* @param target The image data to save the converted color information to |
|||
* @param width The width of the canvas |
|||
* @param height The height of the canvas |
|||
*/ |
|||
export function quantiseColor(x: number, y: number, source: Uint8ClampedArray, target: Uint8ClampedArray, width: number, height: number) { |
|||
|
|||
// TODO: Limit the brightness of each color channel to the set of 4 different values 0, 85, 170, 255.
|
|||
// TODO: Set the RGBA values in the target array accordingly.
|
|||
// TODO:
|
|||
} |
@ -0,0 +1,17 @@ |
|||
/** |
|||
* Posterise the source image and save the result in the target image. |
|||
* Restrict the amount of used brightness levels to four equidistant values. |
|||
* |
|||
* @param x The x coordinate of the pixel to posterise |
|||
* @param y The y coordinate of the pixel to posterise |
|||
* @param source The source image data |
|||
* @param target The image data to save the converted color information to |
|||
* @param width The width of the canvas |
|||
* @param height The height of the canvas |
|||
*/ |
|||
export function quantisegrayscale(x: number, y: number, source: Uint8ClampedArray, target: Uint8ClampedArray, width: number, height: number) { |
|||
|
|||
// TODO: Convert the pixel at position (x, y) in the source array from RGB to XYZ. Limit the
|
|||
// TODO: Limit the brightness to the set of 4 different values 0, 85, 170, 255.
|
|||
// TODO: Set the RGBA values in the target array to this brightness.
|
|||
} |
@ -0,0 +1,49 @@ |
|||
import 'bootstrap'; |
|||
import 'bootstrap/scss/bootstrap.scss'; |
|||
import { gammaAdjust } from './gammacorrection'; |
|||
|
|||
let gammaImageData: ImageData; |
|||
let gammaCtx: CanvasRenderingContext2D; |
|||
let gamma = 1; |
|||
|
|||
window.addEventListener('load', () => { |
|||
|
|||
const gammaSlider = |
|||
document.getElementById("gammaslider") as HTMLInputElement; |
|||
const gammaCanvas = document.getElementById("result") as HTMLCanvasElement; |
|||
if (gammaCanvas === null) |
|||
return; |
|||
gammaCtx = gammaCanvas.getContext("2d"); |
|||
|
|||
const gammaImg = new Image(); |
|||
gammaImg.onload = () => { |
|||
gammaCtx.drawImage(gammaImg, 0, 0); |
|||
gammaImageData = gammaCtx.getImageData( |
|||
0, 0, gammaImg.width, gammaImg.height); |
|||
gammaAdjustImage(); |
|||
}; |
|||
gammaImg.src = "gammacorrection.png"; |
|||
|
|||
gammaSlider.addEventListener('change', e => { |
|||
gamma = Number(gammaSlider.value); |
|||
gammaAdjustImage(); |
|||
}); |
|||
gamma = Number(gammaSlider.value); |
|||
}); |
|||
|
|||
function gammaAdjustImage() { |
|||
const imageData = gammaCtx.getImageData( |
|||
0, 0, |
|||
gammaImageData.width, gammaImageData.height |
|||
); |
|||
for (let width = 0; width < gammaImageData.width; width++) { |
|||
for (let height = 0; height < gammaImageData.height; height++) { |
|||
gammaAdjust(gamma, |
|||
gammaImageData.data, imageData.data, |
|||
width, height, |
|||
gammaImageData.width, gammaImageData.height |
|||
); |
|||
} |
|||
} |
|||
gammaCtx.putImageData(imageData, 0, 0); |
|||
} |
@ -0,0 +1,38 @@ |
|||
import 'bootstrap'; |
|||
import 'bootstrap/scss/bootstrap.scss'; |
|||
|
|||
import { grayscale } from './grayscale'; |
|||
|
|||
function quantise(evt: Event) { |
|||
|
|||
const originalCanvas = document.getElementById("original") as HTMLCanvasElement; |
|||
if (originalCanvas === null) |
|||
return; |
|||
const original = originalCanvas.getContext("2d"); |
|||
original.drawImage(evt.target as HTMLImageElement, 0, 0, 512, 384); |
|||
const originalData = original.getImageData(0, 0, originalCanvas.width, originalCanvas.height); |
|||
|
|||
const grayscaleCanvas = document.getElementById("result") as HTMLCanvasElement; |
|||
const grayscaleContext = grayscaleCanvas.getContext("2d"); |
|||
var pixel = grayscaleContext.createImageData(1, 1); |
|||
const grayscaleData = grayscaleContext.getImageData(0, 0, grayscaleCanvas.width, grayscaleCanvas.height); |
|||
|
|||
for (let y = 0; y < grayscaleCanvas.height; y++) { |
|||
for (let x = 0; x < grayscaleCanvas.width; x++) { |
|||
grayscale(x, y, originalData.data, grayscaleData.data, grayscaleCanvas.width, grayscaleCanvas.height); |
|||
|
|||
// update pixel in HTML context2d
|
|||
for (let i = 0; i < 4; i ++) |
|||
pixel.data[i] = |
|||
grayscaleData.data[(x + y * grayscaleCanvas.width) * 4 + i]; |
|||
grayscaleContext.putImageData(pixel, x, y); |
|||
} |
|||
} |
|||
} |
|||
|
|||
window.addEventListener('load', () => { |
|||
|
|||
const squirrel = new Image(); |
|||
squirrel.onload = quantise; |
|||
squirrel.src = "quantise.jpg"; |
|||
}); |
@ -0,0 +1,38 @@ |
|||
import 'bootstrap'; |
|||
import 'bootstrap/scss/bootstrap.scss'; |
|||
|
|||
import { quantiseColor } from './quantisecolor'; |
|||
|
|||
function quantise(evt: Event) { |
|||
|
|||
const originalCanvas = document.getElementById("original") as HTMLCanvasElement; |
|||
if (originalCanvas === null) |
|||
return; |
|||
const original = originalCanvas.getContext("2d"); |
|||
original.drawImage(evt.target as HTMLImageElement, 0, 0, 512, 384); |
|||
const originalData = original.getImageData(0, 0, originalCanvas.width, originalCanvas.height); |
|||
|
|||
const colorCanvas = document.getElementById("result") as HTMLCanvasElement; |
|||
const color = colorCanvas.getContext("2d"); |
|||
var pixel = color.createImageData(1, 1); |
|||
const colorData = color.getImageData(0, 0, colorCanvas.width, colorCanvas.height); |
|||
|
|||
for (let y = 0; y < colorCanvas.height; y++) { |
|||
for (let x = 0; x < colorCanvas.width; x++) { |
|||
quantiseColor(x, y, originalData.data, colorData.data, colorCanvas.width, colorCanvas.height); |
|||
|
|||
// update pixel in HTML context2d
|
|||
for (let i = 0; i < 4; i ++) |
|||
pixel.data[i] = |
|||
colorData.data[(x + y * colorCanvas.width) * 4 + i]; |
|||
color.putImageData(pixel, x, y); |
|||
} |
|||
} |
|||
} |
|||
|
|||
window.addEventListener('load', () => { |
|||
|
|||
const squirrel = new Image(); |
|||
squirrel.onload = quantise; |
|||
squirrel.src = "quantise.jpg"; |
|||
}); |
@ -0,0 +1,38 @@ |
|||
import 'bootstrap'; |
|||
import 'bootstrap/scss/bootstrap.scss'; |
|||
|
|||
import { quantisegrayscale } from './quantisegrayscale'; |
|||
|
|||
function quantise(evt: Event) { |
|||
|
|||
const originalCanvas = document.getElementById("original") as HTMLCanvasElement; |
|||
if (originalCanvas === null) |
|||
return; |
|||
const original = originalCanvas.getContext("2d"); |
|||
original.drawImage(evt.target as HTMLImageElement, 0, 0, 512, 384); |
|||
const originalData = original.getImageData(0, 0, originalCanvas.width, originalCanvas.height); |
|||
|
|||
const grayscaleCanvas = document.getElementById("result") as HTMLCanvasElement; |
|||
const grayscale = grayscaleCanvas.getContext("2d"); |
|||
var pixel = grayscale.createImageData(1, 1); |
|||
const grayscaleData = grayscale.getImageData(0, 0, grayscaleCanvas.width, grayscaleCanvas.height); |
|||
|
|||
for (let y = 0; y < grayscaleCanvas.height; y++) { |
|||
for (let x = 0; x < grayscaleCanvas.width; x++) { |
|||
quantisegrayscale(x, y, originalData.data, grayscaleData.data, grayscaleCanvas.width, grayscaleCanvas.height); |
|||
|
|||
// update pixel in HTML context2d
|
|||
for (let i = 0; i < 4; i ++) |
|||
pixel.data[i] = |
|||
grayscaleData.data[(x + y * grayscaleCanvas.width) * 4 + i]; |
|||
grayscale.putImageData(pixel, x, y); |
|||
} |
|||
} |
|||
} |
|||
|
|||
window.addEventListener('load', () => { |
|||
|
|||
const squirrel = new Image(); |
|||
squirrel.onload = quantise; |
|||
squirrel.src = "quantise.jpg"; |
|||
}); |