/// Save raw float data to a PNG file, doing automatic brightness adjustments per channel
Save raw float data to a PNG file, doing automatic brightness adjustments per channel
Save raw float data to a PNG file doing automatic brightness adjustments per channel
fn save_f32_image_as_png(data: &[f32], size: Vec2<usize>, name: String) {
        let mut png_buffer = png::GrayImage::new(size.width() as u32, size.height() as u32);
        let mut sorted = Vec::from(data);
        sorted.sort_by(|a, b| a.partial_cmp(b).unwrap_or(Ordering::Less));
        // percentile normalization
        let max = sorted[7 * sorted.len() / 8];
        let min = sorted[1 * sorted.len() / 8];
        // primitive tone mapping
        let tone = |v: f32| (v - 0.5).tanh() * 0.5 + 0.5;
        let max_toned = tone(*sorted.last().unwrap());
        let min_toned = tone(*sorted.first().unwrap());
        // for each pixel, tone map the value
        for (x, y, pixel) in png_buffer.enumerate_pixels_mut() {
            let v = data[(y as usize * size.0 + x as usize)];
            let v = (v - min) / (max - min);
            let v = tone(v);
            let v = (v - min_toned) / (max_toned - min_toned);
            // TODO does the `image` crate expect gamma corrected data?
            *pixel = png::Luma([(v.max(0.0).min(1.0) * 255.0) as u8]);
        }
        png_buffer.save(&name).unwrap();
    }
fn save_f32_image_as_png ( data : & [ f32 ] , size : Vec2 < usize > , name : String ) { let mut png_buffer = png :: GrayImage :: new ( size . width ( ) as u32 , size . height ( ) as u32 ) ; let mut sorted = Vec :: from ( data ) ; sorted . sort_by ( | a , b | a . partial_cmp ( b ) . unwrap_or ( Ordering :: Less ) ) ; // percentile normalization let max = sorted [ 7 * sorted . len ( ) / 8 ] ; let min = sorted [ 1 * sorted . len ( ) / 8 ] ; // primitive tone mapping let tone = | v : f32 | ( v - 0.5 ) . tanh ( ) * 0.5 + 0.5 ; let max_toned = tone ( * sorted . last ( ) . unwrap ( ) ) ; let min_toned = tone ( * sorted . first ( ) . unwrap ( ) ) ; // for each pixel, tone map the value for ( x , y , pixel ) in png_buffer . enumerate_pixels_mut ( ) { let v = data [ ( y as usize * size . 0 + x as usize ) ] ; let v = ( v - min ) / ( max - min ) ; let v = tone ( v ) ; let v = ( v - min_toned ) / ( max_toned - min_toned ) ; // TODO does the `image` crate expect gamma corrected data? * pixel = png :: Luma ( [ ( v . max ( 0.0 ) . min ( 1.0 ) * 255.0 ) as u8 ] ) ; } png_buffer . save ( & name ) . unwrap ( ) ; }
Save raw float data to a PNG file, doing automatic brightness adjustments per channel
Save raw float data to a PNG file doing automatic brightness adjustments per channel
data
&[f32]
size
Vec2<usize>
name
String