You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Handling images by _CoreGraphics_ is too complicated: various formats, old C APIs and painful memory management. _EasyImagy_ provides the easier way to handle images in exchange for some performance.
29
+
Processing images by _CoreGraphics_ is complicated: various formats, old C APIs and painful memory management. _EasyImagy_ provides easier APIs to process images.
30
30
31
-
Typically `Image`s in _EasyImagy_ are used with `RGBA`.`RGBA` is a simple structure declared as follows.
31
+
Typically the `Image` type is used with the `RGBA` type. The`RGBA` is a simple structure declared as follows.
32
32
33
33
```swift
34
-
structRGBA {
35
-
var red: UInt8
36
-
var green: UInt8
37
-
var blue: UInt8
38
-
var alpha: UInt8
34
+
structRGBA<Channel> {
35
+
var red: Channel
36
+
var green: Channel
37
+
var blue: Channel
38
+
var alpha: Channel
39
39
}
40
40
```
41
41
42
-
You can access to a pixel easily using subscripts like `image[x, y]` and its channels by properties `red`, `green`, `blue` and `alpha`.
42
+
You can easily access to pixels using subscripts like `image[x, y]` and also their channels using properties `red`, `green`, `blue` and `alpha`.
43
43
44
-
`Image` and `RGBA`also provide some convenient methods and properties to make it easy to process images. For example, it is possible to convert an image to grayscale combining `Image#map` with `RGBA#gray` in one line as shown below.
44
+
In addition, `Image` and `RGBA` provide some powerful APIs to process images. For example, it is possible to convert an image to grayscale combining `Image.map` with `RGBA.gray` in one line as shown below.
45
45
46
46
```swift
47
-
let result = image.map { $0.gray }
47
+
let grayscale: Image<UInt8> = image.map { $0.gray }
48
+
```
49
+
50
+
Another notable feature of _EasyImagy_ is that the `Image` is a `struct`, i.e. a value type, with copy-on-write. It means
51
+
52
+
-`Image` instances never be shared
53
+
- defensive copying is unnecessary
54
+
- no wastful copying of `Image` instances
55
+
- copying is executed lazily when it is required
56
+
57
+
```swift
58
+
var another = image // Not copied here because of copy-on-write
59
+
another[x, y] =RGBA(0xff0000ff) // Copied here lazily
48
60
```
49
61
50
-
Usage
51
-
---------------------------
62
+
## Usage
52
63
53
64
### Import
54
65
@@ -59,27 +70,35 @@ import EasyImagy
59
70
### Initialization
60
71
61
72
```swift
62
-
let image = Image<RGBA>(named: "ImageName")!
73
+
let image = Image<RGBA<UInt8>>(named: "ImageName")!
74
+
```
75
+
76
+
```swift
77
+
let image = Image<RGBA<UInt8>>(contentsOfFile: "path/to/file")!
63
78
```
64
79
65
80
```swift
66
-
let image = Image<RGBA>(contentsOfFile: "path/to/file")!
81
+
let image = Image<RGBA<UInt8>>(data: Data(/* ... */))!
67
82
```
68
83
69
84
```swift
70
-
let image = Image<RGBA>(data: NSData(/* ... */))!
85
+
let image = Image<RGBA<UInt8>>(uiImage: imageView.image!) // from a UIImage
71
86
```
72
87
73
88
```swift
74
-
let image = Image<RGBA>(uiImage: imageView.image!)!
89
+
let image = Image<RGBA<UInt8>>(width: 640, height: 480, pixels: pixels) // from pixels
75
90
```
76
91
77
92
```swift
78
-
let image = Image<RGBA>(width: 640, height: 480, pixel: .black) // a black image
93
+
let image = Image<RGBA<UInt8>>(width: 640, height: 480, pixel: .black) // a black RGBA image
79
94
```
80
95
81
96
```swift
82
-
let image = Image<RGBA>(width: 640, height: 480, pixels: pixels)
97
+
let image = Image<UInt8>(width: 640, height: 480, pixel: .min) // a black grayscale image
98
+
```
99
+
100
+
```swift
101
+
let image = Image<Bool>(width: 640, height: 480, pixel: false) // a black binary image
83
102
```
84
103
85
104
### Access to a pixel
@@ -97,12 +116,12 @@ image[x, y].alpha = 127
97
116
98
117
```swift
99
118
// Safe get for a pixel
100
-
iflet pixel = image.pixel(x, y) {
119
+
iflet pixel = image.pixelAt(x: x, y: y) {
101
120
print(pixel.red)
102
121
print(pixel.green)
103
122
print(pixel.blue)
104
123
print(pixel.alpha)
105
-
124
+
106
125
print(pixel.gray) // (red + green + blue) / 3
107
126
print(pixel) // formatted like "#FF0000FF"
108
127
} else {
@@ -122,45 +141,46 @@ for pixel in image {
122
141
### Rotation
123
142
124
143
```swift
125
-
let result = image.rotate() //Rotate clockwise
144
+
let result = image.rotated(by: .pi) //Rotated clockwise by π
126
145
```
127
146
128
147
```swift
129
-
let result = image.rotate(-1) //Rotate counterclockwise
148
+
let result = image.rotated(byDegrees: 180) //Rotated clockwise by 180 degrees
130
149
```
131
150
132
151
```swift
133
-
let result = image.rotate(2) // Rotate by 180 degrees
152
+
// Rotated clockwise by π / 4 and fill the background with red
153
+
let result = image.rotated(by: .pi/4, extrapolatedBy: .filling(.red))
134
154
```
135
155
136
156
### Flip
137
157
138
158
```swift
139
-
let result = image.flipX() // Flip Horizontally
159
+
let result = image.xReversed() // Flip Horizontally
140
160
```
141
161
142
162
```swift
143
-
let result = image.flipY() // Flip Vertically
163
+
let result = image.yReversed() // Flip Vertically
144
164
```
145
165
146
166
### Resizing
147
167
148
168
```swift
149
-
let result = image.resize(width: 100, height: 100)
169
+
let result = image.resizedTo(width: 320, height: 240)
150
170
```
151
171
152
172
```swift
153
-
let result = image.resize(width: 100, height: 100,
0 commit comments