Skip to content

Commit a43a30e

Browse files
committed
docs: add examples for affine transformation
1 parent 1fb669c commit a43a30e

12 files changed

+62
-59
lines changed

docs/Tutorials/Applying transform function on images.md

Lines changed: 62 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,11 @@ $$
3737

3838
Each parameter controls specific aspects of the transformation:
3939

40-
`a`, `e`: Scaling (horizontal and vertical)
41-
`b`, `d`: Shearing and rotation
42-
`c`, `f`: Translation (horizontal and vertical)
43-
`g`, `h`: Perspective distortion
44-
`i`: Normalization factor (usually 1)
40+
- `a`, `e`: Scaling (horizontal and vertical)
41+
- `b`, `d`: Shearing and rotation
42+
- `c`, `f`: Translation (horizontal and vertical)
43+
- `g`, `h`: Perspective distortion
44+
- `i`: Normalization factor (usually 1)
4545

4646
## Getting Started
4747

@@ -55,13 +55,12 @@ const image = readSync('/path/to/image.png');
5555

5656
## Affine Transformations
5757

58-
1. Scaling
59-
Scaling changes the size of your image. Parameters a and e control horizontal and vertical scaling respectively.
58+
### Scaling
6059

61-
Uniform Scaling (Maintaining Aspect Ratio)
60+
Scaling changes the size of your image. Parameters a and e control horizontal and vertical scaling respectively.
6261

6362
```ts
64-
// Scale image by factor of 2 (double the size)
63+
// Scale image by factor of 2 (Maintaining Aspect Ratio)
6564
const transformationMatrix = [
6665
[2, 0, 0], // a=2 (horizontal scale), b=0, c=0
6766
[0, 2, 0], // d=0, e=2 (vertical scale), f=0
@@ -70,6 +69,8 @@ const transformationMatrix = [
7069
const scaledImage = image.transform(transformationMatrix);
7170
```
7271

72+
![Scaled image](./images/transformations/lennaScaled.png)
73+
7374
### Non-uniform Scaling
7475

7576
```ts
@@ -82,6 +83,8 @@ const transformationMatrix = [
8283
const stretchedImage = image.transform(transformationMatrix);
8384
```
8485

86+
![Stretched image](./images/transformations/lennaStretched.png)
87+
8588
#### Common Scaling Examples
8689

8790
```ts
@@ -90,20 +93,30 @@ const shrinkMatrix = [
9093
[0.5, 0, 0],
9194
[0, 0.5, 0],
9295
];
96+
```
9397

98+
![Shrunk image](./images/transformations/lennaShrunk.png)
99+
100+
```ts
94101
// Mirror horizontally (flip left-right)
95102
const mirrorMatrix = [
96103
[-1, 0, 0],
97104
[0, 1, 0],
98105
];
106+
```
107+
108+
![Mirrored image](./images/transformations/lennaMirrorred.png)
99109

110+
```ts
100111
// Mirror vertically (flip up-down)
101112
const flipMatrix = [
102113
[1, 0, 0],
103114
[0, -1, 0],
104115
];
105116
```
106117

118+
![Flipped image](./images/transformations/lennaFlipped.png)
119+
107120
### Translation
108121

109122
Translation moves your image to a different position. Parameters `c` and `f` control horizontal and vertical movement.
@@ -116,24 +129,20 @@ const translationMatrix = [
116129
];
117130

118131
const translatedImage = image.transform(translationMatrix);
119-
120-
// Move image 100 pixels left and 50 pixels up
121-
const moveMatrix = [
122-
[1, 0, -100], // Negative values move left
123-
[0, 1, -50], // Negative values move up
124-
];
125132
```
126133

134+
![Translated image](./images/transformations/lennaTranslated.png)
135+
127136
### Rotation
128137

129-
Rotation transforms your image around a point (typically the origin). It uses a combination of parameters a, b, d, and e.
138+
Rotation transforms your image around a point (typically the origin). It uses a combination of parameters `a`, `b`, `d`, and `e`.
130139

131140
For rotation by angle θ (in radians):
132141

133-
`a` = cos(θ)
134-
`b` = -sin(θ)
135-
`d` = sin(θ)
136-
`e` = cos(θ)
142+
- `a` = cos(θ)
143+
- `b` = -sin(θ)
144+
- `d` = sin(θ)
145+
- `e` = cos(θ)
137146

138147
```ts
139148
// Rotate 45 degrees clockwise
@@ -144,38 +153,38 @@ const rotationMatrix = [
144153
];
145154

146155
const rotatedImage = image.transform(rotationMatrix);
147-
148-
// Rotate 90 degrees counter-clockwise
149-
const rotation90Matrix = [
150-
[0, 1, 0], // cos(90°)=0, -sin(90°)=-(-1)=1
151-
[-1, 0, 0], // sin(90°)=1, cos(90°)=0
152-
];
153156
```
154157

158+
![Rotated image](./images/transformations/lennaRotated.png)
159+
155160
### Rotation Around Image Center
156161

157162
To rotate around the image center instead of the origin, combine translation with rotation:
158163

159164
```ts
160-
function rotateAroundCenter(image, angle) {
161-
const centerX = image.width / 2;
162-
const centerY = image.height / 2;
163-
164-
const cos = Math.cos(angle);
165-
const sin = Math.sin(angle);
165+
const angle = Math.PI / 4; //45 degrees
166+
const [centerX, centerY] = image.getCoordinates('center');
166167

167-
// Translate to origin, rotate, translate back
168-
const matrix = [
169-
[cos, -sin, centerX * (1 - cos) + centerY * sin],
170-
[sin, cos, centerY * (1 - cos) - centerX * sin],
171-
];
168+
const cos = Math.cos(angle);
169+
const sin = Math.sin(angle);
172170

173-
return image.transform(matrix);
174-
}
171+
// Translate to origin, rotate, translate back
172+
const matrix = [
173+
[cos, -sin, centerX * (1 - cos) + centerY * sin],
174+
[sin, cos, centerY * (1 - cos) - centerX * sin],
175+
];
175176

176-
const centeredRotation = rotateAroundCenter(image, Math.PI / 6); // 30 degrees
177+
return image.transform(matrix);
177178
```
178179

180+
:::note
181+
Image-js has functions `rotate()` and `transformRotate()`. `rotate()` function allows rotating an image by multiple of 90 degrees.
182+
`transformRotate()` allows rotating an image by any degree. It also allows choosing the axe of rotation. So, for rotation, you have other functions that allow you to perform it.
183+
Current tutorial just demonstrates the basic principle behind transformation of such kind.
184+
:::
185+
186+
![Rotated by center image](./images/transformations/lennaRotatedCenter.png)
187+
179188
### Shearing
180189

181190
Shearing skews the image, making rectangles appear as parallelograms. Parameters b and d control shearing.
@@ -186,20 +195,30 @@ const horizontalShearMatrix = [
186195
[1, 0.5, 0], // b=0.5 creates horizontal shear
187196
[0, 1, 0],
188197
];
198+
```
189199

200+
![Horizontally sheared image](./images/transformations/lennaHorizontalShear.png)
201+
202+
```ts
190203
// Vertical shear - lean the image upward
191204
const verticalShearMatrix = [
192205
[1, 0, 0],
193206
[0.3, 1, 0], // d=0.3 creates vertical shear
194207
];
208+
```
209+
210+
![Vertically sheared image](./images/transformations/lennaVerticalShear.png)
195211

212+
```ts
196213
// Combined shearing
197214
const combinedShearMatrix = [
198215
[1, 0.5, 0], // Horizontal shear
199216
[0.3, 1, 0], // Vertical shear
200217
];
201218
```
202219

220+
![Combined shearing](./images/transformations/lennaCombinedShear.png)
221+
203222
### Complex Affine Transformations
204223

205224
You can combine multiple transformations by multiplying matrices or applying them sequentially:
@@ -260,8 +279,8 @@ const destPoints = [
260279
[30, 280], // Bottom-left
261280
];
262281

263-
// Calculate transformation matrix (implementation depends on library)
264-
const projectionMatrix = calculateProjectionMatrix(sourcePoints, destPoints);
282+
// Get transformation matrix using 4 points
283+
const projectionMatrix = getPerspectiveWarp(sourcePoints);
265284
const projectedImage = image.transform(projectionMatrix);
266285
```
267286

@@ -326,23 +345,7 @@ function correctDocumentPerspective(image, corners) {
326345
// corners should be [topLeft, topRight, bottomRight, bottomLeft]
327346
const [tl, tr, br, bl] = corners;
328347

329-
// Calculate document dimensions
330-
const width = Math.max(distance(tl, tr), distance(bl, br));
331-
const height = Math.max(distance(tl, bl), distance(tr, br));
332-
333-
// Target rectangle corners
334-
const targetCorners = [
335-
[0, 0],
336-
[width, 0],
337-
[width, height],
338-
[0, height],
339-
];
340-
341-
const matrix = calculateProjectionMatrix(corners, targetCorners);
348+
const matrix = getPerspectiveWarp(corners{});
342349
return image.transform(matrix);
343350
}
344-
345-
function distance(p1, p2) {
346-
return Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2);
347-
}
348351
```
235 KB
Loading
273 KB
Loading
251 KB
Loading
273 KB
Loading
201 KB
Loading
258 KB
Loading
583 KB
Loading
180 KB
Loading
311 KB
Loading

0 commit comments

Comments
 (0)