-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbitmap.ts
136 lines (103 loc) · 3.29 KB
/
bitmap.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { BitmapBufferAPI, Decoder, Encoder } from "https://deno.land/x/bitmap/mod.ts";
export interface ColorPixel {
r: number;
g: number;
b: number;
}
export type MonoPixel = number;
export type LogicPixel = boolean;
class Bitmap {
private _width;
private _height;
private _data;
get width() { return this._width; }
get height() { return this._height; }
constructor(width: number, height: number, data?: BitmapBufferAPI) {
this._width = width;
this._height = height;
if(data) {
this._data = data;
} else {
this._data = new BitmapBufferAPI(4 * width * height);
}
}
public static async fromFile(path: string) {
const data = await Deno.readFile(path);
const decoder = Decoder(BitmapBufferAPI.from(data));
return new Bitmap(decoder.width, decoder.height, decoder.data);
}
public copy() {
return { ...this };
}
public getPixel(x: number, y: number) : ColorPixel {
const pos = (y * this._width + x) * 4;
return {
r: this._data[pos + 3],
g: this._data[pos + 2],
b: this._data[pos + 1],
};
}
public getMono(x: number, y: number) : MonoPixel {
const pos = (y * this._width + x) * 4;
return this._data[pos + 1];
}
public getLogic(x: number, y: number) : LogicPixel {
const pos = (y * this._width + x) * 4;
return this._data[pos + 1] != 0;
}
public setPixel(x: number, y: number, pixel: ColorPixel) {
const pos = (y * this._width + x) * 4;
this._data[pos+1] = pixel.b;
this._data[pos+2] = pixel.g;
this._data[pos+3] = pixel.r;
}
public setMono(x: number, y: number, pixel: MonoPixel) {
const pos = (y * this._width + x) * 4;
this._data[pos+1] = pixel;
this._data[pos+2] = pixel;
this._data[pos+3] = pixel;
}
public setLogic(x: number, y: number, pixel: LogicPixel) {
const pos = (y * this._width + x) * 4;
this._data[pos+1] = pixel ? 255 : 0;
this._data[pos+2] = pixel ? 255 : 0;
this._data[pos+3] = pixel ? 255 : 0;
}
public async save(path: string) {
const bitmap = Encoder({
data: this._data,
width: this.width,
height: this.height
});
await Deno.writeFile(path, bitmap.data);
}
public and(b: Bitmap) : number {
if(this.width != this.width || b.height != b.height)
throw new Error("Różne rozmiary");
let area = 0;
for(let i = 0; i < this.width; i++) {
for(let j = 0; j < this.height; j++) {
if(this.getLogic(i, j) && b.getLogic(i, j))
area++;
else
this.setLogic(i, j, false);
}
}
return area;
}
public getMinMax() {
let min = 256;
let max = 0;
for(let i = 0; i < this.width; i++) {
for(let j = 0; j < this.height; j++) {
const pixel = this.getMono(i, j);
if(pixel < min)
min = pixel;
if(pixel > max)
max = pixel;
}
}
return [min, max];
}
}
export default Bitmap;