readme.md (3253B)
1 # icns-rs 2 3 > Easily create icns container images from pngs. Make your apps look sharp. 4 5 icns is an image format for MacOS ([Apple Icon Image Format](https://en.wikipedia.org/wiki/Apple_Icon_Image_format)), which is essentially a container format that rolls together one or more png encoded images. 6 7 These icons are used by Mac `.app` bundles, allowing them to choose the appropriate resolution icon for the given context. Typically an icns will contain several versions of a png all at different resolutions, from a max of 1024x1024 pixels down to 32x32 pixels, suitable for high-dpi retina screens. 8 9 The most common ways to generate icns files are: 10 - `iconutil`, which is an esoteric Mac native cli utility that is opaque and cumbersome to use. 11 - `ImageMagick`, which adds a large dependency to your project for such a simple use case. 12 13 This is a Rust port of my Go project [icns](https://github.com/jackmordaunt/icns). 14 15 Where the Go project builds on the standard library `image.Image` interface, this library builds on the image abstractions from [Piston](https://github.com/pistondevelopers) developer's [image](https://github.com/pistondevelopers/image) crate. 16 17 ## Usage 18 19 See the examples folder for more usage. 20 21 ### Generate a fractal and encode as icns 22 > Adapted from [fractal.rs](https://github.com/PistonDevelopers/image/blob/master/examples/fractal.rs) 23 24 ```rust 25 use std::fs::File; 26 use std::io::BufWriter; 27 use num_complex; 28 use icns::Encoder; 29 use image::{self, ConvertBuffer}; 30 31 fn main() { 32 let imgx = 1024; 33 let imgy = 1024; 34 35 let scalex = 3.0 / imgx as f32; 36 let scaley = 3.0 / imgy as f32; 37 38 // Create a new ImgBuf with width: imgx and height: imgy. 39 let mut imgbuf = image::ImageBuffer::new(imgx, imgy); 40 41 // Generate fractal. 42 for x in 0..imgx { 43 for y in 0..imgy { 44 let cx = y as f32 * scalex - 1.5; 45 let cy = x as f32 * scaley - 1.5; 46 47 let c = num_complex::Complex::new(-0.4, 0.6); 48 let mut z = num_complex::Complex::new(cx, cy); 49 50 let mut i = 0; 51 while i < 255 && z.norm() <= 2.0 { 52 z = z * z + c; 53 i += 1; 54 } 55 56 let pixel = imgbuf.get_pixel_mut(x, y); 57 let data = (*pixel as image::Rgb<u8>).0; 58 *pixel = image::Rgb([data[0], i as u8, data[2]]); 59 } 60 } 61 62 // Open output file. 63 let mut output = BufWriter::new(File::create("fractal.icns") 64 .expect("creating output file")); 65 66 // Encode the image as icns. 67 // Note that we use ConvertBuffer trait to convert from RGB to RGBA. 68 Encoder::new(&mut output) 69 .encode(&imgbuf.convert()) 70 .expect("encoding icns"); 71 } 72 ``` 73 74 ## Features 75 - [x] Encode icns (mvp) `RgbaImage -> .icns` 76 - [x] Parallel resizing (thanks [rayon](https://github.com/rayon-rs/rayon)) 77 - [x] Lanczos3 interpolation 78 - [ ] Decode largest image from icns into standalone png 79 - [x] Simple and robust cli app 80 - [x] Flag based use 81 - [x] Shell pipe use 82 - [ ] Unit tests 83 84 ## Feedback Wanted 85 86 I'm relatively new to Rust. If you have any tips, see any non-idiomatic code, or notice ways to make the library more ergonomic and powerful: I'd love to hear from you.