@@ -163,15 +163,15 @@ To rotate around the image center instead of the origin, combine translation wit
163
163
164
164
``` ts
165
165
const angle = Math .PI / 4 ; // 45 degrees
166
- const [centerX, centerY] = image .getCoordinates (' center' );
166
+ const center = image .getCoordinates (' center' );
167
167
168
168
const cos = Math .cos (angle );
169
169
const sin = Math .sin (angle );
170
170
171
171
// Translate to origin, rotate, translate back
172
172
const matrix = [
173
- [cos , - sin , centerX * (1 - cos ) + centerY * sin ],
174
- [sin , cos , centerY * (1 - cos ) - centerX * sin ],
173
+ [cos , - sin , center . column * (1 - cos ) + center . row * sin ],
174
+ [sin , cos , center . row * (1 - cos ) - center . column * sin ],
175
175
];
176
176
177
177
return image .transform (matrix );
@@ -262,31 +262,41 @@ const perspectiveImage = image.transform(perspectiveMatrix);
262
262
263
263
The most common use of projective transformation is mapping an image to fit within four corner points:
264
264
265
+ ![ Corrected perspective] ( ./images/transformations/card.png ) ;
266
+
265
267
``` ts
266
- // Define source corners (original image corners)
268
+ const image = readSync (' path/to/file.png' );
269
+ // Define source corners (original image points) and destination image width and height.
270
+ // Width and height can be omitted. In this case width and height will be calculated from points.
267
271
const sourcePoints = [
268
- [0 , 0 ], // Top-left
269
- [image .width , 0 ], // Top-right
270
- [image .width , image .height ], // Bottom-right
271
- [0 , image .height ], // Bottom-left
272
- ];
273
-
274
- // Define destination corners (where you want them to appear)
275
- const destPoints = [
276
- [50 , 100 ], // Top-left moved
277
- [300 , 80 ], // Top-right
278
- [320 , 250 ], // Bottom-right
279
- [30 , 280 ], // Bottom-left
272
+ [
273
+ { column: 55 , row: 140 },
274
+ { column: 680 , row: 38 },
275
+ { column: 840 , row: 340 },
276
+ { column: 145 , row: 460 },
277
+ ],
278
+ { width: 725 , height: 425 },
280
279
];
281
280
282
- // Get transformation matrix using 4 points
281
+ // Get transformation matrix using 4 points and `getPerspectiveWarp` function.
283
282
const projectionMatrix = getPerspectiveWarp (sourcePoints );
284
- const projectedImage = image .transform (projectionMatrix );
283
+ const projectedImage = image .transform (matrix .matrix , {
284
+ width: matrix .width ,
285
+ height: matrix .height ,
286
+ inverse: true ,
287
+ });
285
288
```
286
289
290
+ ![ Corrected perspective] ( ./images/transformations/card-perspectiveWarp.png ) ;
291
+
287
292
### Keystone Correction
288
293
289
- Correcting perspective distortion (like photographing a screen at an angle):
294
+ Correcting perspective distortion (like photographing a screen at an angle). Let's take this image
295
+ as an example.
296
+
297
+ ![ Keystone image] ( ./images/transformations/buildings.jpg )
298
+
299
+ A common problem when taking photos of tall buildings is that they can look as if they're leaning backwards. This is known as the "keystone effect" (or the "tombstone effect"), and it can be a very distracting form of distortion in your images.
290
300
291
301
``` ts
292
302
// Correct keystone effect - make trapezoid into rectangle
@@ -298,54 +308,3 @@ const keystoneMatrix = [
298
308
299
309
const correctedImage = image .transform (keystoneMatrix );
300
310
```
301
-
302
- ## Practical Examples and Use Cases
303
-
304
- ### Creating Thumbnails with Proper Aspect Ratio
305
-
306
- ``` ts
307
- function createThumbnail(image , maxWidth , maxHeight ) {
308
- const scaleX = maxWidth / image .width ;
309
- const scaleY = maxHeight / image .height ;
310
- const scale = Math .min (scaleX , scaleY ); // Maintain aspect ratio
311
-
312
- const thumbnailMatrix = [
313
- [scale , 0 , 0 ],
314
- [0 , scale , 0 ],
315
- ];
316
-
317
- return image .transform (thumbnailMatrix );
318
- }
319
- ```
320
-
321
- ### Photo Straightening
322
-
323
- ``` ts
324
- function straightenPhoto(image , angleDegrees ) {
325
- const angle = (angleDegrees \* Math .PI ) / 180 ;
326
- const centerX = image .width / 2 ;
327
- const centerY = image .height / 2 ;
328
-
329
- const cos = Math .cos (- angle ); // Negative for correction
330
- const sin = Math .sin (- angle );
331
-
332
- const matrix = [
333
- [cos , - sin , centerX * (1 - cos ) + centerY * sin ],
334
- [sin , cos , centerY * (1 - cos ) - centerX * sin ],
335
- ];
336
-
337
- return image .transform (matrix );
338
- }
339
- ```
340
-
341
- ### Document Scanning Perspective Correction
342
-
343
- ``` ts
344
- function correctDocumentPerspective(image , corners ) {
345
- // corners should be [topLeft, topRight, bottomRight, bottomLeft]
346
- const [tl, tr, br, bl] = corners ;
347
-
348
- const matrix = getPerspectiveWarp (corners {});
349
- return image .transform (matrix );
350
- }
351
- ```
0 commit comments