protected override void OnFormClosing(FormClosingEventArgs e) { base.OnFormClosing(e); if (m_imageNormal != null) { m_imageNormal.Dispose(); } if (m_imageHeight != null) { m_imageHeight.Dispose(); } m_device.Dispose(); }
public void Dispose() { if (m_image != null) { m_image.Dispose(); } m_image = null; m_contentRectangle = Rectangle.Empty; }
public void UpdateFromWebPageImage(ImageFile _imagesWebPage) { if (_imagesWebPage == null) { throw new Exception("Invalid image!"); } if (m_thumbnail != null) { m_thumbnail.Dispose(); } m_compressedContent = null; // Clear compressed content as it will be repalced with our new thumbnail anyway // Create a tiny thumbnail from the image uint thumbnailHeight = Mathf.Min(_imagesWebPage.Height * THUMBNAIL_WIDTH / _imagesWebPage.Width, THUMBNAIL_HEIGHT); // At most our preferred ratio => we must crop the full page! float imageScale = (float)_imagesWebPage.Width / THUMBNAIL_WIDTH; m_thumbnail = new ImageFile(THUMBNAIL_WIDTH, thumbnailHeight, PIXEL_FORMAT.BGR8, DEFAULT_PROFILE); // Note that it's important to create a 24-bits format here to be able to save as JPEG! // Read "height" scanlines float4[] sourceScanline = new float4[_imagesWebPage.Width]; float4[] targetScanline = new float4[THUMBNAIL_WIDTH]; for (uint Y = 0; Y < thumbnailHeight; Y++) { uint sourceY = (uint)(imageScale * Y); _imagesWebPage.ReadScanline(sourceY, sourceScanline); for (uint X = 0; X < THUMBNAIL_WIDTH; X++) { targetScanline[X] = sourceScanline[(uint)(imageScale * (X + 0.5f))]; } m_thumbnail.WriteScanline(Y, targetScanline); } // Notify? m_owner.NotifyThumbnailChanged(this); }
void TestBuildImage( BUILD_TESTS _type ) { try { switch ( _type ) { case BUILD_TESTS.FILL_PIXEL: // Write pixel per pixel m_imageFile = new ImageFile( 378, 237, ImageFile.PIXEL_FORMAT.RGB16, new ColorProfile( ColorProfile.STANDARD_PROFILE.sRGB ) ); for ( uint Y=0; Y < m_imageFile.Height; Y++ ) { for ( uint X=0; X < m_imageFile.Width; X++ ) { float R = (float) (1+X) / m_imageFile.Width; float G = (float) (1+Y) / m_imageFile.Height; m_imageFile[X,Y] = new float4( R, G, 1.0f-0.5f*(R+G), 1 ); } } break; case BUILD_TESTS.FILL_SCANLINE: // Write scanline per scanline m_imageFile = new ImageFile( 378, 237, ImageFile.PIXEL_FORMAT.RGB16, new ColorProfile( ColorProfile.STANDARD_PROFILE.sRGB ) ); float4[] scanline = new float4[m_imageFile.Width]; for ( uint Y=0; Y < m_imageFile.Height; Y++ ) { for ( uint X=0; X < m_imageFile.Width; X++ ) { float R = 1.0f - (float) (1+X) / m_imageFile.Width; float G = (float) (1+Y) / m_imageFile.Height; scanline[X].Set( R, G, 1.0f-0.5f*(R+G), 1 ); } m_imageFile.WriteScanline( Y, scanline ); } break; // Buddhabrot case BUILD_TESTS.ADDITIVE_BUDDHABROT: { m_imageFile = new ImageFile( 378, 237, ImageFile.PIXEL_FORMAT.RGB16, new ColorProfile( ColorProfile.STANDARD_PROFILE.sRGB ) ); uint W = m_imageFile.Width; uint H = m_imageFile.Height; float2 Z, Z0; int iterations = 50; float4 inc = (1.0f / iterations) * float4.One; float zoom = 2.0f; float invZoom = 1.0f / zoom; #if DIRECT_WRITE // Either directly accumulate to image for ( uint Y=0; Y < H; Y++ ) { Z0.y = zoom * (Y - 0.5f * H) / H; for ( uint X=0; X < W; X++ ) { Z0.x = zoom * (X - 0.5f * W) / H; Z = Z0; for ( int i=0; i < iterations; i++ ) { Z.Set( Z.x*Z.x - Z.y*Z.y + Z0.x, 2.0f * Z.x * Z.y + Z0.y ); int Nx = (int) (invZoom * Z.x * H + 0.5f * W); int Ny = (int) (invZoom * Z.y * H + 0.5f * H); if ( Nx >= 0 && Nx < W && Ny >= 0 && Ny < H ) { // float4 tagada = (float4) m_imageFile[(uint)Nx,(uint)Ny]; // tagada += inc; // m_imageFile[(uint)Nx,(uint)Ny] = tagada; m_imageFile.Add( (uint)Nx, (uint)Ny, inc ); } } } } #else // Or accumulate to a temp array and write result (this is obviously faster!) float[,] accumulators = new float[W,H]; for ( uint Y=0; Y < H; Y++ ) { Z0.y = zoom * (Y - 0.5f * H) / H; for ( uint X=0; X < W; X++ ) { Z0.x = zoom * (X - 0.5f * W) / H; Z = Z0; for ( int i=0; i < iterations; i++ ) { Z.Set( Z.x*Z.x - Z.y*Z.y + Z0.x, 2.0f * Z.x * Z.y + Z0.y ); int Nx = (int) (invZoom * Z.x * H + 0.5f * W); int Ny = (int) (invZoom * Z.y * H + 0.5f * H); if ( Nx >= 0 && Nx < W && Ny >= 0 && Ny < H ) accumulators[Nx, Ny] += inc.x; } } } float4 temp = new float4(); for ( uint Y=0; Y < H; Y++ ) { for ( uint X=0; X < W; X++ ) { float a = accumulators[X,Y]; temp.Set( a, a, a, 1 ); m_imageFile[X,Y] = temp; } } #endif } break; case BUILD_TESTS.STRESS_BUILD: ImageFile.PIXEL_FORMAT[] formats = new ImageFile.PIXEL_FORMAT[] { ImageFile.PIXEL_FORMAT.R8, ImageFile.PIXEL_FORMAT.RG8, ImageFile.PIXEL_FORMAT.RGB8, ImageFile.PIXEL_FORMAT.RGBA8, ImageFile.PIXEL_FORMAT.R16, // ImageFile.PIXEL_FORMAT.RG16, ImageFile.PIXEL_FORMAT.RGB16, ImageFile.PIXEL_FORMAT.RGBA16, ImageFile.PIXEL_FORMAT.R16F, ImageFile.PIXEL_FORMAT.RG16F, ImageFile.PIXEL_FORMAT.RGB16F, ImageFile.PIXEL_FORMAT.RGBA16F, ImageFile.PIXEL_FORMAT.R32F, // ImageFile.PIXEL_FORMAT.RG32F, ImageFile.PIXEL_FORMAT.RGB32F, ImageFile.PIXEL_FORMAT.RGBA32F, }; Random RNG = new Random( 1 ); for ( int i=0; i < 1000; i++ ) { uint W = 100 + (uint) (1000 * RNG.NextDouble()); uint H = 100 + (uint) (1000 * RNG.NextDouble()); ImageFile.PIXEL_FORMAT format = formats[RNG.Next( formats.Length-1 )]; m_imageFile = new ImageFile( W, H,format, new ColorProfile( ColorProfile.STANDARD_PROFILE.sRGB ) ); m_imageFile.Dispose(); } m_imageFile = new ImageFile( 1000, 1000, ImageFile.PIXEL_FORMAT.RGBA8, new ColorProfile( ColorProfile.STANDARD_PROFILE.sRGB ) ); m_imageFile.Clear( new float4( 0, 1, 0.2f, 1 ) ); break; } panelBuild.Bitmap = m_imageFile.AsBitmap; } catch ( Exception _e ) { MessageBox.Show( "Error: " + _e.Message ); } }
private void buttonVoidAndCluster_Click(object sender, EventArgs e) { uint textureSize = 1U << integerTrackbarControlTexturePOT.Value; uint randomSeed = (uint)integerTrackbarControlRandomSeed.Value; if (m_blueNoiseVoidAndCluster != null) { m_blueNoiseVoidAndCluster.Dispose(); } // m_blueNoiseVoidAndCluster = new ImageFile( textureSize, textureSize, PIXEL_FORMAT.R8, new ColorProfile( ColorProfile.STANDARD_PROFILE.sRGB ) ); m_blueNoiseVoidAndCluster = new ImageFile(textureSize, textureSize, PIXEL_FORMAT.R16, new ColorProfile(ColorProfile.STANDARD_PROFILE.LINEAR)); float4[] scanline = new float4[textureSize]; ImageFile graphStatistics = new ImageFile((uint)panelImageSpectrum.Width, (uint)panelImageSpectrum.Height, PIXEL_FORMAT.RGBA8, new ColorProfile(ColorProfile.STANDARD_PROFILE.sRGB)); float4 black = new float4(0, 0, 0, 1); float2 rangeX = new float2(0, 10000); // float2 rangeY = new float2( -10, 10 ); // float2 rangeY = new float2( -1, 2 ); float2 rangeY = new float2(0, 1); float sigma_i = floatTrackbarControlVariance.Value; // Default, recommended value by Ulichney is 1.5 DateTime startTime = DateTime.Now; this.Enabled = false; GeneratorVoidAndClusterGPU generator = new GeneratorVoidAndClusterGPU(m_device, (uint)(Math.Log(m_blueNoiseVoidAndCluster.Width) / Math.Log(2.0))); generator.Generate(randomSeed, sigma_i, 0.025f, (float _progress, float[,] _texture, List <float> _statistics) => { m_blueNoiseVoidAndCluster.WritePixels((uint X, uint Y, ref float4 _color) => { float V = _texture[X, Y]; _color.Set(V, V, V, 1.0f); }); if (m_blueNoiseVoidAndCluster.Width < panelImage.Width) { panelImage.Bitmap = m_blueNoiseVoidAndCluster.AsTiledBitmap((uint)panelImage.Width, (uint)panelImage.Height); } else { panelImage.Bitmap = m_blueNoiseVoidAndCluster.AsBitmap; } TimeSpan deltaTime = DateTime.Now - startTime; labelAnnealingScore.Text = "Time: " + deltaTime.ToString(@"hh\:mm\:ss") + " ► Progress: " + (100.0f * _progress).ToString("G3") + "%"; labelAnnealingScore.Refresh(); Application.DoEvents(); /* // Plot statistics * int lastX = 0; * graphStatistics.Clear( float4.One ); * // graphStatistics.PlotGraphAutoRangeY( black, rangeX, ref rangeY, ( float _X ) => { * graphStatistics.PlotGraph( black, rangeX, rangeY, ( float _X ) => { * int X = Math.Max( 0, Math.Min( _statistics.Count-1, (int) (_statistics.Count * _X / rangeX.y) ) ); * // return _statistics[X]; * * // Integrate... * float sum = 0.0f; * for ( int x=lastX; x <= X; x++ ) * sum += _statistics[x]; * sum *= X != lastX ? 1.0f / (X - lastX) : 0.0f; * lastX = X; * * return sum; * } ); * graphStatistics.PlotAxes( black, rangeX, rangeY, 1000.0f, 100.0f ); * panelImageSpectrum.Bitmap = graphStatistics.AsBitmap; * //*/ // if ( _progress == 1.0f ) { // using ( System.IO.FileStream S = new System.IO.FileInfo( "indices.txt" ).Create() ) { // using ( System.IO.StreamWriter W = new System.IO.StreamWriter( S ) ) { // for ( int i=0; i < _statistics.Count; i++ ) { // W.WriteLine( (int) Math.Floor( m_blueNoiseVoidAndCluster.Width*m_blueNoiseVoidAndCluster.Height* _statistics[i] ) ); // } // } // } // } }); this.Enabled = true; m_blueNoiseVoidAndCluster.Save(new System.IO.FileInfo("BlueNoise" + m_blueNoiseVoidAndCluster.Width + "x" + m_blueNoiseVoidAndCluster.Height + "_VoidAndCluster.png")); // Quick FFT panelImageSpectrum.Bitmap = ComputeSpectrum(m_blueNoiseVoidAndCluster, 2.0f * textureSize).AsBitmap; }
private void buttonSolidAngleAlgorithm_Click(object sender, EventArgs e) { uint textureSize = 1U << integerTrackbarControlTexturePOT.Value; uint dimensions = (uint)integerTrackbarControlVectorDimension.Value; uint randomSeed = (uint)integerTrackbarControlRandomSeed.Value; uint iterations = (uint)integerTrackbarControlAnnealingIterations.Value; if (m_blueNoiseAnnealing != null) { m_blueNoiseAnnealing.Dispose(); } m_blueNoiseAnnealing = new ImageFile(textureSize, textureSize, PIXEL_FORMAT.RGBA8, new ColorProfile(ColorProfile.STANDARD_PROFILE.sRGB)); float4[] scanline = new float4[textureSize]; ImageFile graphStatistics = new ImageFile((uint)panelImageSpectrum.Width, (uint)panelImageSpectrum.Height, PIXEL_FORMAT.RGBA8, new ColorProfile(ColorProfile.STANDARD_PROFILE.sRGB)); float4 black = new float4(0, 0, 0, 1); float2 rangeX = new float2(0, 10000); // float2 rangeY = new float2( -10, 10 ); // float2 rangeY = new float2( -1, 2 ); float2 rangeY = new float2(0, 100); float sigma_i = floatTrackbarControlVariance.Value; // Default, recommended value is 2.1 float sigma_s = 1.0f; // Default, recommended value // uint notificationIterationsCount = Math.Max( 1U, (uint) (0.025f * iterations) ); uint notificationIterationsCount = 1000; DateTime startTime = DateTime.Now; this.Enabled = false; GeneratorSolidAngleGPU generator = new GeneratorSolidAngleGPU(m_device, (uint)(Math.Log(m_blueNoiseAnnealing.Width) / Math.Log(2.0)), dimensions); generator.Generate(randomSeed, iterations, sigma_i, sigma_s, radioButtonNeighborMutations.Checked, notificationIterationsCount, (uint _iterationIndex, uint _mutationsRate, float _energyScore, Array _texture, List <float> _statistics) => { switch (dimensions) { case 1: { float[,] texture = _texture as float[, ]; m_blueNoiseAnnealing.WritePixels((uint X, uint Y, ref float4 _color) => { float V = texture[X, Y]; _color.Set(V, V, V, 1.0f); }); break; } case 2: { float2[,] texture = _texture as float2[, ]; m_blueNoiseAnnealing.WritePixels((uint X, uint Y, ref float4 _color) => { float2 V = texture[X, Y]; _color.Set(V.x, V.y, 0, 1.0f); }); break; } } if (m_blueNoiseAnnealing.Width < panelImage.Width) { panelImage.Bitmap = m_blueNoiseAnnealing.AsTiledBitmap((uint)panelImage.Width, (uint)panelImage.Height); } else { panelImage.Bitmap = m_blueNoiseAnnealing.AsBitmap; } TimeSpan deltaTime = DateTime.Now - startTime; labelAnnealingScore.Text = "Time: " + deltaTime.ToString(@"hh\:mm\:ss") + " ► Score: " + _energyScore + " - Iterations = " + _iterationIndex + " - Mutations Rate: " + _mutationsRate; labelAnnealingScore.Refresh(); Application.DoEvents(); /* // Plot statistics * int lastX = 0; * graphStatistics.Clear( float4.One ); * // graphStatistics.PlotGraphAutoRangeY( black, rangeX, ref rangeY, ( float _X ) => { * graphStatistics.PlotGraph( black, rangeX, rangeY, ( float _X ) => { * int X = Math.Max( 0, Math.Min( _statistics.Count-1, (int) (_statistics.Count - 10000.0f + _X) ) ); * // return _statistics[X]; * * // Integrate... * float sum = 0.0f; * for ( int x=lastX; x <= X; x++ ) * sum += _statistics[x]; * sum *= X != lastX ? 1.0f / (X - lastX) : 0.0f; * lastX = X; * * return sum; * } ); * graphStatistics.PlotAxes( black, rangeX, rangeY, 1000.0f, 100.0f ); * panelImageSpectrum.Bitmap = graphStatistics.AsBitmap; * //*/ }); this.Enabled = true; m_blueNoiseAnnealing.Save(new System.IO.FileInfo("BlueNoise" + m_blueNoiseAnnealing.Width + "x" + m_blueNoiseAnnealing.Height + "_SimulatedAnnealing" + dimensions + "D.png")); // Quick FFT panelImageSpectrum.Bitmap = ComputeSpectrum(m_blueNoiseAnnealing, 2.0f * textureSize).AsBitmap; }
// Release all resources public void Dispose() { FileOpen = false; ImageFile.Dispose(); }