Beispiel #1
0
        protected void TestConvertLDR2HDR( System.IO.FileInfo[] _LDRImageFileNames, bool _responseCurveOnly, bool _RAW )
        {
            try {

                // Load the LDR images
                List< ImageFile >	LDRImages = new List< ImageFile >();
                foreach ( System.IO.FileInfo LDRImageFileName in _LDRImageFileNames )
                    LDRImages.Add( new ImageFile( LDRImageFileName ) );

                // Retrieve the shutter speeds
                List< float >	shutterSpeeds = new List< float >();
                foreach ( ImageFile LDRImage in LDRImages ) {
                    shutterSpeeds.Add( LDRImage.Metadata.ExposureTime );
                }

                // Retrieve filter type
                Bitmap.FILTER_TYPE	filterType = Bitmap.FILTER_TYPE.NONE;
                if ( radioButtonFilterNone.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.NONE;
                } else if ( radioButtonFilterGaussian.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.SMOOTHING_GAUSSIAN;
                } else if ( radioButtonFilterGaussian2Pass.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.SMOOTHING_GAUSSIAN_2_PASSES;
                } else if ( radioButtonFilterTent.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.SMOOTHING_TENT;
                } else if ( radioButtonFilterCurveFitting.Checked ) {
                     filterType = Bitmap.FILTER_TYPE.GAUSSIAN_PLUS_CURVE_FITTING;
                }

            // Check EXR save is working!
            // ImageFile	pipo = new ImageFile();
            // 			pipo.ConvertFrom( LDRImages[0], ImageFile.PIXEL_FORMAT.RGB32F );
            // pipo.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromJPG\Result.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_DEFAULT );

            // Check bitmap->tone mapped image file is working
            // {
            // 	Bitmap	tempBitmap = new Bitmap();
            // 	List< float >	responseCurve = new List< float >( 256 );
            // 	for ( int i=0; i < 256; i++ )
            // 		responseCurve.Add( (float) (Math.Log( (1+i) / 256.0 ) / Math.Log(2)) );
            // 	tempBitmap.LDR2HDR( new ImageFile[] { LDRImages[4] }, new float[] { 1.0f }, responseCurve, 1.0f );
            //
            // 	ImageFile	tempHDR = new ImageFile();
            // 	tempBitmap.ToImageFile( tempHDR, new ColorProfile( ColorProfile.STANDARD_PROFILE.LINEAR ) );
            //
            // 	ImageFile	tempToneMappedHDR = new ImageFile();
            // 	tempToneMappedHDR.ToneMapFrom( tempHDR,( float3 _HDRColor, ref float3 _LDRColor ) => {
            // 		// Just do gamma un-correction, don't care about actual HDR range...
            // 		_LDRColor.x = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.x ), 1.0f / 2.2f );	// Here we need to clamp negative values that we sometimes get in EXR format
            // 		_LDRColor.y = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.y ), 1.0f / 2.2f );	//  (must be coming from the log encoding I suppose)
            // 		_LDRColor.z = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.z ), 1.0f / 2.2f );
            // 	} );
            //
            // 	panel1.Bitmap = tempToneMappedHDR.AsBitmap;
            // 	return;
            // }

                //////////////////////////////////////////////////////////////////////////////////////////////
                // Build the HDR device-independent bitmap
            //				uint bitsPerPixel = _RAW ? 12U : 8U;
            uint	bitsPerPixel = _RAW ? 8U : 8U;
            float	quality = _RAW ? 3.0f : 3.0f;

                Bitmap.HDRParms	parms = new Bitmap.HDRParms() {
                    _inputBitsPerComponent = bitsPerPixel,
                    _luminanceFactor = 1.0f,
                    _curveSmoothnessConstraint = 1.0f,
                    _quality = quality,
                    _responseCurveFilterType = filterType
                };

                ImageUtility.Bitmap	HDRImage = new ImageUtility.Bitmap();

            //				HDRImage.LDR2HDR( LDRImages.ToArray(), shutterSpeeds.ToArray(), parms );

                // Compute response curve
                List< float >	responseCurve = new List< float >();
                Bitmap.ComputeCameraResponseCurve( LDRImages.ToArray(), shutterSpeeds.ToArray(), parms._inputBitsPerComponent, parms._curveSmoothnessConstraint, parms._quality, responseCurve );

                // Filter
                List< float >	responseCurve_filtered = new List< float >();
            //				Bitmap.FilterCameraResponseCurve( responseCurve, responseCurve_filtered, Bitmap.FILTER_TYPE.CURVE_FITTING );
                Bitmap.FilterCameraResponseCurve( responseCurve, responseCurve_filtered, filterType );

            // 				using ( System.IO.FileStream S = new System.IO.FileInfo( "../../responseCurve3.float" ).Create() )
            // 					using ( System.IO.BinaryWriter W = new System.IO.BinaryWriter( S ) ) {
            // 						for ( int i=0; i < 256; i++ )
            // 							W.Write( responseCurve[i] );
            // 					}

                // Write info
                string		info = "Exposures:\r\n";
                foreach ( float shutterSpeed in shutterSpeeds )
                    info += " " + shutterSpeed + "s + ";
                info += "\r\nLog2 exposures (EV):\r\n";
                foreach ( float shutterSpeed in shutterSpeeds )
                    info += " " + (float) (Math.Log( shutterSpeed ) / Math.Log(2)) + "EV + ";
                info += "\r\n\r\n";

                if ( _responseCurveOnly ) {
                    //////////////////////////////////////////////////////////////////////////////////////////////
                    // Render the response curve as a graph
             					ImageFile	tempCurveBitmap = new ImageFile( 1024, 768, ImageFile.PIXEL_FORMAT.RGB8, new ColorProfile( ColorProfile.STANDARD_PROFILE.sRGB ) );

                    int			responseCurveSizeMax = responseCurve.Count-1;

                    float2		rangeX = new float2( 0, responseCurveSizeMax+1 );
                    float2		rangeY = new float2( 0, 500 );
                    tempCurveBitmap.Clear( new float4( 1, 1, 1, 1 ) );
            //					tempCurveBitmap.PlotGraphAutoRangeY( red, rangeX, ref rangeY, ( float x ) => {
                    tempCurveBitmap.PlotGraph( red, rangeX, rangeY, ( float x ) => {
                        int		i0 = (int) Math.Min( responseCurveSizeMax, Math.Floor( x ) );
                        int		i1 = (int) Math.Min( responseCurveSizeMax, i0+1 );
                        float	g0 = responseCurve[i0];
                        float	g1 = responseCurve[i1];
                        float	t = x - i0;
            //						return g0 + (g1-g0) * t;
                        return (float) Math.Pow( 2.0f, g0 + (g1-g0) * t );
                    } );
                    tempCurveBitmap.PlotGraph( blue, rangeX, rangeY, ( float x ) => {
                        int		i0 = (int) Math.Min( responseCurveSizeMax, Math.Floor( x ) );
                        int		i1 = (int) Math.Min( responseCurveSizeMax, i0+1 );
                        float	g0 = responseCurve_filtered[i0];
                        float	g1 = responseCurve_filtered[i1];
                        float	t = x - i0;
            //						return g0 + (g1-g0) * t;
                        return (float) Math.Pow( 2.0f, g0 + (g1-g0) * t );
                    } );
            //					tempCurveBitmap.PlotAxes( black, rangeX, rangeY, 8, 2 );

                    info += "• Linear range Y = [" + rangeY.x + ", " + rangeY.y + "]\r\n";

                    rangeY = new float2( -4, 4 );
                    tempCurveBitmap.PlotLogGraphAutoRangeY( black, rangeX, ref rangeY, ( float x ) => {
            //					tempCurveBitmap.PlotLogGraph( black, rangeX, rangeY, ( float x ) => {
                        int		i0 = (int) Math.Min( responseCurveSizeMax, Math.Floor( x ) );
                        int		i1 = (int) Math.Min( responseCurveSizeMax, i0+1 );
                        float	g0 = responseCurve[i0];
                        float	g1 = responseCurve[i1];
                        float	t = x - i0;
            //						return g0 + (g1-g0) * t;
                        return (float) Math.Pow( 2.0f, g0 + (g1-g0) * t );
                    }, -1.0f, 2.0f );
                    tempCurveBitmap.PlotLogGraph( blue, rangeX, rangeY, ( float x ) => {
            //					tempCurveBitmap.PlotLogGraph( black, rangeX, rangeY, ( float x ) => {
                        int		i0 = (int) Math.Min( responseCurveSizeMax, Math.Floor( x ) );
                        int		i1 = (int) Math.Min( responseCurveSizeMax, i0+1 );
                        float	g0 = responseCurve_filtered[i0];
                        float	g1 = responseCurve_filtered[i1];
                        float	t = x - i0;
            //						return g0 + (g1-g0) * t;
                        return (float) Math.Pow( 2.0f, g0 + (g1-g0) * t );
                    }, -1.0f, 2.0f );
                    tempCurveBitmap.PlotLogAxes( black, rangeX, rangeY, -16, 2 );

                    info += "• Log2 range Y = [" + rangeY.x + ", " + rangeY.y + "]\r\n";

             					panelOutputHDR.Bitmap = tempCurveBitmap.AsBitmap;

                } else {
                    //////////////////////////////////////////////////////////////////////////////////////////////
                    // Recompose the HDR image
                    HDRImage.LDR2HDR( LDRImages.ToArray(), shutterSpeeds.ToArray(), responseCurve_filtered, 1.0f );

                    // Display as a tone-mapped bitmap
                    ImageFile	tempHDR = new ImageFile();
                    HDRImage.ToImageFile( tempHDR, new ColorProfile( ColorProfile.STANDARD_PROFILE.LINEAR ) );

                    if ( _RAW ) {
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromRAW\Result.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_DEFAULT );
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromRAW\Result_B44LC.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_B44 | ImageFile.SAVE_FLAGS.SF_EXR_LC );
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromRAW\Result_noLZW.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_NONE );
                    } else {
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromJPG\Result.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_DEFAULT );
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromJPG\Result_B44LC.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_B44 | ImageFile.SAVE_FLAGS.SF_EXR_LC );
                        tempHDR.Save( new System.IO.FileInfo( @"..\..\Images\Out\LDR2HDR\FromJPG\Result_noLZW.exr" ), ImageFile.FILE_FORMAT.EXR, ImageFile.SAVE_FLAGS.SF_EXR_NONE );
                    }

                    ImageFile	tempToneMappedHDR = new ImageFile();
                    tempToneMappedHDR.ToneMapFrom( tempHDR,( float3 _HDRColor, ref float3 _LDRColor ) => {
                        // Just do gamma un-correction, don't care about actual HDR range...
                        _LDRColor.x = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.x ), 1.0f / 2.2f );	// Here we need to clamp negative values that we sometimes get in EXR format
                        _LDRColor.y = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.y ), 1.0f / 2.2f );	//  (must be coming from the log encoding I suppose)
                        _LDRColor.z = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.z ), 1.0f / 2.2f );
                    } );

                    panelOutputHDR.Bitmap = tempToneMappedHDR.AsBitmap;
                }

                textBoxHDR.Text = info;

            } catch ( Exception _e ) {
                MessageBox.Show( "Error: " + _e.Message );

            // Show debug image
            // panelLoad.Bitmap = Bitmap.DEBUG.AsBitmap;
            }
        }
Beispiel #2
0
        void TestLoadImage( LOADING_TESTS _type )
        {
            try {
                switch ( _type ) {
                    // BMP
                    case LOADING_TESTS.BMP_RGB:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\BMP\RGB8.bmp" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;
                    case LOADING_TESTS.BMP_RGBA:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\BMP\RGBA8.bmp" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;

                    // GIF
                    case LOADING_TESTS.GIF_RGB8P:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\GIF\RGB8P.gif" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;

                    // JPG
                    case LOADING_TESTS.JPEG_R8:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\JPG\R8.jpg" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;
                    case LOADING_TESTS.JPEG_RGB8:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\JPG\RGB8.jpg" ) );
            //						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\JPG\RGB8_ICC.jpg" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;

                    // PNG
                            // 8-bits
                    case LOADING_TESTS.PNG_R8P:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\PNG\R8P.png" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;
                    case LOADING_TESTS.PNG_RGB8:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\PNG\RGB8.png" ) );
            //						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\PNG\RGB8_SaveforWeb.png" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;
                    case LOADING_TESTS.PNG_RGBA8:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\PNG\RGBA8.png" ) );
            //						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\PNG\RGBA8_SaveforWeb.png" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;
                            // 16-bits
                    case LOADING_TESTS.PNG_RGB16:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\PNG\RGB16.png" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;

                    // TGA
                    // @TODO => Check why I can't retrieve my custom metas!
                    case LOADING_TESTS.TGA_RGB8:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TGA\RGB8.tga" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;
                    case LOADING_TESTS.TGA_RGBA8:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TGA\RGBA8.tga" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;

                    // TIFF
                            // 8-bits
                    case LOADING_TESTS.TIFF_RGB8:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TIFF\RGB8.tif" ) );
            //						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TIFF\RGB8_ICC.tif" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;
                            // 16-bits
                    case LOADING_TESTS.TIFF_RGB16:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TIFF\RGB16.tif" ) );
            //						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TIFF\RGB16_ICC.tif" ) );
                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;

                    // RAW
                    case LOADING_TESTS.CRW:
                        m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\CRW\CRW_7967.CRW" ) );
            //						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7971.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7971.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7972.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7973.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7974.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7975.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7976.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7977.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7978.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7979.crw" ) );
            // 						m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\LDR2HDR\FromRAW\CRW_7980.crw" ) );

                        panelLoad.Bitmap = m_imageFile.AsBitmap;
                        break;

                    default:
                        // High-Dynamic Range Images
                        switch ( _type ) {
                                // HDR
                            case LOADING_TESTS.HDR_RGBE:
                                m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\HDR\RGB32F.hdr" ) );
                                break;

                                // EXR
                            case LOADING_TESTS.EXR_RGB32F:
             								m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\EXR\RGB32F.exr" ) );
                                break;

                                // TIFF
                            case LOADING_TESTS.TIFF_RGB16F:
                                    // 16-bits floating-point
                                m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TIFF\RGB16F.tif" ) );
            //								m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TIFF\RGB16F_ICC.tif" ) );
                                break;

            // Pom (2016-11-14) This crashes as FreeImage is not capable of reading 32-bits floating point TIFs but I think I don't care, we have enough formats!
            // 							case LOADING_TESTS.TIFF_RGB32F:
            // 									// 32-bits floating-point
            // 								m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TIFF\RGB32F.tif" ) );
            // //							m_imageFile.Load( new System.IO.FileInfo( @"..\..\Images\In\TIFF\RGB32F_ICC.tif" ) );
            // 								break;

                            default:
                                throw new Exception( "Unhandled format!" );
                        }

                        ImageFile	tempLDR = new ImageFile();
                        tempLDR.ToneMapFrom( m_imageFile, ( float3 _HDRColor, ref float3 _LDRColor ) => {
                            // Do nothing (linear space to gamma space without care!)
            //							_LDRColor = _HDRColor;

                            // Just do gamma un-correction, don't care about actual HDR range...
                            _LDRColor.x = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.x ), 1.0f / 2.2f );	// Here we need to clamp negative values that we sometimes get in EXR format
                            _LDRColor.y = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.y ), 1.0f / 2.2f );	//  (must be coming from the log encoding I suppose)
                            _LDRColor.z = (float) Math.Pow( Math.Max( 0.0f, _HDRColor.z ), 1.0f / 2.2f );
                        } );
                        panelLoad.Bitmap = tempLDR.AsBitmap;
                    break;
             				}

                // Write out metadata
                MetaData		MD = m_imageFile.Metadata;
                ColorProfile	Profile = MD.ColorProfile;
                textBoxEXIF.Lines = new string[] {
                    "File Format: " + m_imageFile.FileFormat,
                    "Pixel Format: " + m_imageFile.PixelFormat + (m_imageFile.HasAlpha ? " (ALPHA)" : " (NO ALPHA)"),
                    "",
                    "Profile:",
                    "  • Chromaticities: ",
                    "    R = " + Profile.Chromas.Red.ToString(),
                    "    G = " + Profile.Chromas.Green.ToString(),
                    "    B = " + Profile.Chromas.Blue.ToString(),
                    "    W = " + Profile.Chromas.White.ToString(),
                    "    Recognized chromaticities = " + Profile.Chromas.RecognizedChromaticity,
                    "  • Gamma Curve: " + Profile.GammaCurve.ToString(),
                    "  • Gamma Exponent: " + Profile.GammaExponent.ToString(),
                    "",
                    "Gamma Found in File = " + MD.GammaSpecifiedInFile,
                    "",
                    "MetaData:",
                    "  • ISO Speed = " + (MD.ISOSpeed_isValid ? MD.ISOSpeed.ToString() : "N/A"),
                    "  • Exposure Time = " + (MD.ExposureTime_isValid? (MD.ExposureTime > 1.0f ? (MD.ExposureTime + " seconds") : ("1/" + (1.0f / MD.ExposureTime) + " seconds")) : "N/A"),
                    "  • Tv = " + (MD.Tv_isValid ? MD.Tv + " EV" : "N/A"),
                    "  • Av = " + (MD.Av_isValid ? MD.Av + " EV" : "N/A"),
                    "  • F = 1/" + (MD.FNumber_isValid ? MD.FNumber + " stops" : "N/A"),
                    "  • Focal Length = " + (MD.FocalLength_isValid ? MD.FocalLength + " mm" : "N/A"),
                };

            } catch ( Exception _e ) {
                MessageBox.Show( "Error: " + _e.Message );
            }
        }