Skip to content

Commit 72713d5

Browse files
Fix height/width being undefined when creating a Jimp from a canvas
1 parent 6047422 commit 72713d5

File tree

5 files changed

+90
-8
lines changed

5 files changed

+90
-8
lines changed

packages/core/src/index.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,18 @@ export function createJimp<
281281
throw new Error("data must be a Buffer");
282282
}
283283

284-
return new CustomJimp({ ...bitmap, data }) as InstanceType<
285-
typeof CustomJimp
286-
> &
287-
ExtraMethodMap;
284+
if (
285+
typeof bitmap.height !== "number" ||
286+
typeof bitmap.width !== "number"
287+
) {
288+
throw new Error("bitmap must have width and height");
289+
}
290+
291+
return new CustomJimp({
292+
height: bitmap.height,
293+
width: bitmap.width,
294+
data,
295+
}) as InstanceType<typeof CustomJimp> & ExtraMethodMap;
288296
}
289297

290298
/**

packages/docs/src/content/docs/guides/browser.mdx

+27-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ To use it simply import `jimp` instead.
2525

2626
## Usage
2727

28-
There are two main ways to use Jimp in the browser.
28+
There are a few main ways to use Jimp in the browser.
2929

3030
### With hosted file
3131

@@ -64,6 +64,32 @@ function handleFile(e: React.ChangeEvent<HTMLInputElement>) {
6464
input.addEventListener("change", handleFile);
6565
```
6666

67+
### Using Canvas
68+
69+
You can also use Jimp with a canvas.
70+
71+
```ts
72+
const canvas = document.getElementById("my-canvas");
73+
const ctx = canvas.getContext("2d");
74+
75+
// Load the canvas into a Jimp instance
76+
const image = await Jimp.fromBitmap(
77+
ctx.getImageData(0, 0, canvas.width, canvas.height)
78+
);
79+
80+
// Manipulate the image
81+
image.greyscale();
82+
83+
const imageData = new ImageData(
84+
new Uint8ClampedArray(image.bitmap.data),
85+
image.bitmap.width,
86+
image.bitmap.height
87+
);
88+
89+
// Write back to the canvas
90+
ctx.putImageData(imageData, 0, 0);
91+
```
92+
6793
## Using Fonts
6894

6995
Jimp supports loading fonts from a URL or a file path.

packages/docs/src/content/docs/guides/migrate-to-v1.mdx

+7-2
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,20 @@ async function main() {
8888

8989
### `Jimp.fromBitmap`
9090

91-
You can load an image from a bitmap.
91+
You can load an image (or canvas data) from a bitmap.
9292
In v0 this was done through the constructor.
9393
In v1 it is done through the `Jimp.fromBitmap` method.
9494

9595
```js
9696
import { Jimp } from "jimp";
9797

9898
async function main() {
99-
const image = await Jimp.fromBitmap(bitmap);
99+
const canvas = document.getElementById("my-canvas");
100+
const ctx = canvas.getContext("2d");
101+
102+
const image = await Jimp.fromBitmap(
103+
ctx.getImageData(0, 0, canvas.width, canvas.height)
104+
);
100105
}
101106
```
102107

packages/jimp/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
},
1919
"scripts": {
2020
"lint": "eslint .",
21-
"test": "vitest",
21+
"test": "vitest --exclude '**/*.browser.test.ts'",
2222
"test:browser": "vitest --config vitest.config.browser.mjs",
2323
"build": "tshy",
2424
"build:browser": "rollup -c",
+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { expect, test, describe } from "vitest";
2+
import { Jimp } from "./index.js";
3+
4+
describe("Canvas", () => {
5+
test("should be able to create a Jimp from a canvas", async () => {
6+
const canvas = document.createElement("canvas");
7+
const ctx = canvas.getContext("2d")!;
8+
9+
// make all the pixels red
10+
ctx.fillStyle = "red";
11+
ctx.fillRect(0, 0, canvas.width, canvas.height);
12+
13+
const beforeValue = ctx.getImageData(0, 0, canvas.width, canvas.height)
14+
.data[0];
15+
16+
const image = await Jimp.fromBitmap(
17+
ctx.getImageData(0, 0, canvas.width, canvas.height)
18+
);
19+
20+
// The jimp image is red
21+
expect(image.bitmap.data[0]).toBe(255);
22+
expect(image.bitmap.data[1]).toBe(0);
23+
expect(image.bitmap.data[2]).toBe(0);
24+
expect(image.bitmap.data[3]).toBe(255);
25+
26+
// Modify the image
27+
image.greyscale();
28+
29+
const imageData = new ImageData(
30+
new Uint8ClampedArray(image.bitmap.data),
31+
image.bitmap.width,
32+
image.bitmap.height
33+
);
34+
35+
// Write back to the canvas
36+
ctx.putImageData(imageData, 0, 0);
37+
38+
// The canvas should have changed
39+
expect(beforeValue).not.toBe(
40+
ctx.getImageData(0, 0, canvas.width, canvas.height).data[0]
41+
);
42+
});
43+
});

0 commit comments

Comments
 (0)