0

Xử lý ảnh dễ dàng trong swift (Phần 2)

1.7 Resize

resize

Để resize ảnh, ta sử dụng hàm sau
let result = image.resize(width: 100, height: 100)

let result = image.resize(width: 100, height: 100,
    interpolationQuality: kCGInterpolationNone) // Nearest neighbor

1.8 Cắt ảnh

catanh

Chúng ta không cần phải copy pixel khi cắt ảnh mà chỉ cần đơn giản như sau
let resultOrNil = image[0..<100][0..<100] // Nếu thừa ra : phần thừa sẽ là `nil`

1.9 Xử lý ảnh

Tương tự như Array, nhưng ở đây chúng ta dùng map để xử lý ảnh

1.9.1 Gray Scale

let result = image.map { (pixel: Pixel) -> Pixel in
    Pixel(gray: pixel.gray)
}
// Shortened form
let result = image.map { Pixel(gray: $0.gray) }

1.9.2 Ảnh đen trắng

let result = image.map { (pixel: Pixel) -> Pixel in
    pixel.gray < 128 ? Pixel.black : Pixel.white
}
// Shortened form
let result = image.map { $0.gray < 128 ? Pixel.black : Pixel.white }

1.9.3 Ảnh đen trắng (chỉnh theo giá trị cho trước(threshold))

let threshold = UInt8(image.reduce(0) { $0 + $1.grayInt } / image.count)
let result = image.map { $0.gray < threshold ? Pixel.black : Pixel.white }

1.9.4 Smooth Filtering

ảnh

Sử dụng đồng thời map và Fragment(mảnh cắt), chúng ta có thể thực hiện được nhiều filter khác nhau. Đơn giản như đoạn code sau
let result = image.map { x, y, pixel in
    image[(y - 1)...(y + 1)][(x - 1)...(x + 1)].map {
        Pixel.mean($0)
    } ?? pixel
}

1.9.5 Ứng dụng trong Gaussian Filtering

ảnh

let weights = [
    1,  4,  6,  4, 1,
    4, 16, 24, 16, 4,
    6, 24, 36, 24, 6,
    4, 16, 24, 16, 4,
    1,  4,  6,  4, 1,
]
let result = image.map { x, y, pixel in
    image[(y - 2)...(y + 2)][(x - 2)...(x + 2)].map {
        Pixel.weightedMean(zip(weights, $0))
    } ?? pixel
}

2. Lý do EasyImagy's Image không phải là Class mà là dạng cấu trúc (Structure)

Trước tiên xin được nhấn mạnh: Image trong EasyImagy là dạng cấu trúc (structure) chứ không phải dạng Class
Image ở đây giống như Array sử dụng cỹ thuật Copy-on-write, do đó hầu như không cần thiết phải thực hiện thao tác copy ảnh giống như ở Class. Nếu Image là dạng Class, ở một số trường hợp chúng ta buộc phải thực hiện thao tác copy dữ liệu image
Ví dụ khi chúng ta khởi tạo một Immutable Class và trong đó có sử dụng image. Nếu imageClass để đảm bảo tính toàn vẹn của Immutable Class chúng ta cần copy image vào. Tuy nhiên trong rất nhiều trường hợp chúng ta không thay đổi object đã được tạo đó. Còn khi image là một thể cấu trúc và sử dụng kỹ thuật copy-on-write: Chỉ khi chúng ta thay đổi dữ liệu copy thì lúc đó quá trình copy mới thực sự xảy ra (bình thường thì chỉ là copy địa chỉ mà thôi, tương tự như kiểu String ở trong Java). Dữ liệu của ảnh hầu như là không nhỏ, do đó khi chúng ta ít sử dụng thao tác copy trực tiếp sẽ tiết kiệm được nhiều tài nguyên, tối ưu hoá phần mềm hơn (hehe)

3. Install

3.1 Carthage

Thư viện có support Carthage, khi muốn sử dụng chúng ta chỉ cần thêm một dòng vào file Carfile

github "koher/EasyImagy" >= 0.1.0

3.2 Manual Labor

Khi muốn import EasyImagy.xcodeproj vào Project hoặc Workspace, chúng ta chỉ cần thêm EasyImagy.xcodeproj vào Embedded Binaries

4. Kết luận

Khi sử dụng thư viện EasyImagy trong Swift chúng ta có thể xử lý pixel của ảnh một cách đơn giản và dễ dàng hơn rất nhiều. Vậy khi lập trình liên quan đến xử lý ảnh, các bạn hãy tham khảo bộ thư viện này nhé !!!! (lay2)


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.