/// <summary>
        /// Result will always be 3-channel float image
        /// inputScale: a value of 1 should represent 100cd/m² -> inputScale can be used to setup this (NaN for auto calculation)
        /// </summary>
        public PixImage <float> Denoise(PixImage <float> img, float inputScale = float.NaN)
        {
            var output = new PixImage <float>(img.Size.X, img.Size.Y, 3);

            Denoise(img, null, null, output, inputScale);
            return(output);
        }
Beispiel #2
0
        public BitmapSource ToBitmapSource(double dpi)
        {
            var storeFormats = GetStoreFormats(typeof(T), Format);
            var vol          = Volume;

            if (Format == Col.Format.BW)
            {
                long sx = vol.SX, sy = vol.SY;

                var bitImage = new PixImage <byte>(Format, 1 + (Size.X - 1) / 8, Size.Y, 1);
                var bitData  = bitImage.Volume.Data;
                var pixData  = ToPixImage <byte>().Volume.Data;

                CompressPixels(ToPixImage <byte>(), bitImage);

                return(BitmapSource.Create(
                           (int)sx, (int)sy, dpi, dpi,
                           storeFormats.E0, null, bitData, bitImage.IntStride));
            }
            else if (Format != storeFormats.E1)
            {
                var saveImage = new PixImage <T>(storeFormats.E1, this);
                vol = saveImage.Volume;
            }

            return(BitmapSource.Create(
                       (int)vol.SX, (int)vol.SY, 96, 96,
                       storeFormats.E0, null, vol.Data, IntStride));
        }
Beispiel #3
0
        public static void ConvertTiffToDDS2(string tiffPath, bool overrideExisting = false)
        {
            string ddsPath = Path.ChangeExtension(tiffPath, ".dds");

            if (overrideExisting || !StorageConfig.FileExists(ddsPath))
            {
                var image = PixImage.Create(tiffPath, PixLoadOptions.UseSystemImage);
                // image.SaveAsImage(pngPath);

                var outFormat = image.PixFormat == PixFormat.ByteGray ?
                                Rendering.AardvarkFormat.L8 : Rendering.AardvarkFormat.Dxt5;

                var target = SlimDx9TextureConvertible.CreateFile(
                    new SlimDx9TextureConvertible.SlimDx9TextureParameters()
                {
                    AardvarkFormat = outFormat,
                    AardvarkUsage  = AardvarkUsage.None,
                    FileName       = ddsPath,
                    Pool           = Pool.Scratch,
                    MipMapLevels   = 0
                });

                var con = image.Convertible();
                con.ConvertInto(target);
            }
        }
Beispiel #4
0
        public void CompressNode(IBatchNode node, string TempPath, double Compression)
        {
            //Get the image
            Stream InputImage = new MemoryStream();

            InputImage = node.NodeData.ValueSet.ReadFile("InputImage").ReadData();
            Bitmap fromStream = new Bitmap(InputImage);
            //Convert this to a PixImage
            PixImage Image = new PixImage();

            Image.Import(fromStream);
            //Now we have a bitmap we need to save it to the temporary file location
            //Get the file path
            string fPath = TempPath;

            //Get a node ID
            fPath = fPath + @"\" + node.NodeData.BatchId + "_" + node.NodeData.NodeId.ToString() + ".jpg";
            //Convert the compression to an int
            int comp = Convert.ToInt32(Compression);

            PixImageStorage.Save(Image, PixFileType.Jpeg, fPath, new PixJpegCompressionSettings(ColorFormat.Rgb, PixCompression.ProgressiveJpeg, comp), OpenFileMode.CreateAlways);
            //Now we want to try and read that file and save it back
            try
            {
                byte[] f = File.ReadAllBytes(fPath);
                node.NodeData.ValueSet.WriteFileData("OutputFile", f, ".jpg");
                //Now delete the files
                File.Delete(fPath);
            }
            catch (IOException e)
            {
                MessageBox.Show(e.Message);
            }
        }
        public void MipMapCreate1x1()
        {
            Init();
            var pix = new PixImage <byte>(1, 1, 4);
            var mip = PixImageMipMap.Create(pix);

            Assert.IsTrue(mip.LevelCount == 1);
        }
        public void MipMapCreate3x3()
        {
            Init();
            var pix = new PixImage <byte>(3, 3, 4);
            var mip = PixImageMipMap.Create(pix);

            Assert.IsTrue(mip.LevelCount == 2);
        }
        public void MipMapCreate257()
        {
            Init();
            var pix = new PixImage <byte>(257, 257, 4);
            var mip = PixImageMipMap.Create(pix);

            Assert.IsTrue(mip.LevelCount == 9);
        }
        /// <summary>
        /// Denoises the input image as lightmap to the output image buffer
        /// inputScale: a value of 1 should a luminance(?) of 100cd/m² -> inputScale can be used to setup this (NaN for auto calculation)
        /// </summary>
        public void DenoiseLightmap(PixImage <float> color, PixImage <float> outImage, bool directional = false, float inputScale = float.NaN)
        {
            if (color.ChannelCount < 3 || color.ChannelCount > 4)
            {
                throw new ArgumentException("Image must have 3 or 4 channels");
            }
            if (outImage.ChannelCount < 3 || outImage.ChannelCount > 4)
            {
                throw new ArgumentException("Output image must have 3 or 4 channels");
            }

            var width  = color.Size.X;
            var height = color.Size.Y;

            if (outImage.Size.X != width || outImage.Size.Y != height)
            {
                throw new ArgumentException("Ouput image size does not match with input");
            }

            // Oidn only supports 3 channel images -> use pixelStride
            var pixelStride    = color.ChannelCount * 4;
            var outPixelStride = outImage.ChannelCount * 4;

            var colorPtr  = GCHandle.Alloc(color.Data, GCHandleType.Pinned);
            var outputPtr = GCHandle.Alloc(outImage.Data, GCHandleType.Pinned);

            // Create a denoising filter
            var filter = OidnAPI.oidnNewFilter(m_device, "RTLightmap"); // optimized filter for HDR lightmaps

            OidnAPI.oidnSetSharedFilterImage(filter, "color", colorPtr.AddrOfPinnedObject(), ImageFormat.Float3, width, height, 0, pixelStride, pixelStride * width);
            OidnAPI.oidnSetSharedFilterImage(filter, "output", outputPtr.AddrOfPinnedObject(), ImageFormat.Float3, width, height, 0, outPixelStride, outPixelStride * width);
            if (!inputScale.IsNaN())
            {
                OidnAPI.oidnSetFilter1f(filter, "inputScale", inputScale);                      // default=NaN
            }
            if (directional)
            {
                OidnAPI.oidnSetFilter1b(filter, "directional", true);              // default=false
            }
            OidnAPI.oidnCommitFilter(filter);

            // Filter the image
            OidnAPI.oidnExecuteFilter(filter);

            colorPtr.Free();
            outputPtr.Free();

            // Check for errors
            if (OidnAPI.oidnGetDeviceError(m_device, out var errorMessage) != Error.None)
            {
                Report.Warn("Error: {0}", errorMessage);
            }

            // Cleanup
            OidnAPI.oidnReleaseFilter(filter);
        }
        public void PixImage_ToSystemDrawingBitmap()
        {
            using (var stream = new MemoryStream(TestImageBuffer))
            {
                var a = PixImage.Create(stream);
                var b = a.ToSystemDrawingBitmap();

                Assert.IsTrue(a.Size.X == b.Width && a.Size.Y == b.Height);
            }
        }
Beispiel #10
0
        public Editor()
        {
            InitializeComponent();
            _image = new PixImage(100, 100);
            var layer = new ColorMatrix(_image.Width, _image.Height);

            layer.Bitmap.SetPixel(50, 50, System.Drawing.Color.Blue);
            _image.Layers.Add(layer);
            DrawImage();
        }
Beispiel #11
0
        public static void CopyTest(string dir)
        {
            var idir      = Path.Combine(dir, "in");
            var odir      = Path.Combine(dir, "out");
            var src       = new PixImage <byte>(Path.Combine(idir, "rgb8.jpg")); //.ToGrayscalePixImage();
            var image     = new PixImage <byte>(src.Format, src.Size);
            var srcvolume = src.Volume;
            // var copyvol = srcvolume.Copy(); // does not work, creates default volume layout!
            var copyvol = srcvolume.CopyToImage(); // works since it creates default image layout!

            image.Volume = copyvol;
            image.SaveAsImage(Path.Combine(idir, "rgb8-copied.jpg"));
        }
        public void MipMapCreate57x11()
        {
            Init();
            var pix = new PixImage <byte>(57, 11, 4);
            var mip = PixImageMipMap.Create(pix);

            Assert.IsTrue(mip.LevelCount == 6);
            //level 0: 57x11
            //level 1: 28x5
            //level 2: 14x2
            //level 3: 7x1
            //level 4: 3x1
            //level 5: 1x1
        }
Beispiel #13
0
        static void Denoise(Device device, string file)
        {
            var img4Chan = (PixImage <float>)PixImage.Create(file);
            var img      = img4Chan.ToPixImage <float>(Col.Format.RGB);

            Report.BeginTimed("Denoise");
            var resultImg = device.Denoise(img, 10);

            Report.End();

            var outFile = Path.GetFileNameWithoutExtension(file) + "_dn.exr";

            resultImg.SaveAsImage(outFile);
        }
Beispiel #14
0
        public static void PolygonDemo(string dir)
        {
            // This code produces tiny tiff images that demonstrate the pixel-
            // level precision of SetMonotonePolygonFilledRaw.

            var tris = new[] {
                new { Tri = new V2d[] { new V2d(7.7, 2.5), new V2d(11.7, 2.5), new V2d(9.8, 0.8) }, Col = C3b.DarkGreen },
                new { Tri = new V2d[] { new V2d(11.7, 2.5), new V2d(7.7, 2.5), new V2d(9.5, 5.2) }, Col = C3b.Green },
                new { Tri = new V2d[] { new V2d(7, 4), new V2d(5, 6), new V2d(8, 7) }, Col = C3b.Green },
                new { Tri = new V2d[] { new V2d(1, 1), new V2d(2, 4), new V2d(6, 2) }, Col = C3b.Green },
                new { Tri = new V2d[] { new V2d(7, 4), new V2d(1, 6), new V2d(5, 6) }, Col = C3b.DarkGreen },
                new { Tri = new V2d[] { new V2d(7, 4), new V2d(8, 7), new V2d(9.5, 5.5) }, Col = C3b.DarkGreen },
                new { Tri = new V2d[] { new V2d(13.5, 5.5), new V2d(13.5, 7.5), new V2d(15.5, 5.5) }, Col = C3b.Green },
                new { Tri = new V2d[] { new V2d(15.5, 5.5), new V2d(13.5, 7.5), new V2d(15.5, 7.5) }, Col = C3b.DarkGreen },
                new { Tri = new V2d[] { new V2d(15, 0), new V2d(13.5, 1.5), new V2d(14.5, 2.5) }, Col = C3b.Green },
                new { Tri = new V2d[] { new V2d(14.5, 2.5), new V2d(13.5, 1.5), new V2d(14.5, 2.5) }, Col = C3b.Red },
                new { Tri = new V2d[] { new V2d(7.5, 0.5), new V2d(6.5, 1.5), new V2d(7.5, 1.5) }, Col = C3b.Red },
                new { Tri = new V2d[] { new V2d(6.3, 0.3), new V2d(5.3, 1.3), new V2d(6.3, 1.3) }, Col = C3b.Red },
                new { Tri = new V2d[] { new V2d(11.5, 4.5), new V2d(11.5, 6.5), new V2d(12.5, 5.5) }, Col = C3b.DarkGreen },
            };

            var triImg = new PixImage <byte>(16, 8, 3);
            var tMat   = triImg.GetMatrix <C3b>();

            Report.BeginTimed("polygon demo triangles");
            foreach (var t in tris)
            {
                tMat.SetMonotonePolygonFilledRaw(t.Tri, t.Col);
            }
            triImg.SaveAsImage(Path.Combine(dir, "polygon-triangles.tiff"));
            Report.End();

            var polyImg = new PixImage <byte>(10, 10, 3);

            var pMat = polyImg.GetMatrix <C3b>();

            V2d[] poly = new V2d[] {
                new V2d(4, 1),
                new V2d(1, 3),
                new V2d(2, 6),
                new V2d(2.1, 6.1),
                new V2d(5, 7),
                new V2d(8, 5),
                new V2d(9, 3),
            };
            Report.BeginTimed("polygon demo polygon");
            pMat.SetMonotonePolygonFilledRaw(poly, C3b.Red);
            polyImg.SaveAsImage(Path.Combine(dir, "polygon-polygon.tiff"));
            Report.End();
        }
Beispiel #15
0
        public static void Difference(string dir)
        {
            var idir      = Path.Combine(dir, "in");
            var odir      = Path.Combine(dir, "out");
            var hiliteImg = new PixImage <float>(Path.Combine(idir, "ref_hilite.png"));
            var luxImg    = new PixImage <float>(Path.Combine(idir, "ref_lux.png"));

            var diffImg = new PixImage <float>(Col.Format.RGB, hiliteImg.Size);

            diffImg.Volume.SetMap2(hiliteImg.Volume, luxImg.Volume, (a, b) => Fun.Abs(b - a));

            var outImg = diffImg.ToPixImage <ushort>();

            outImg.SaveAsImage(Path.Combine(odir, "difference.tiff"));
        }
        public void SaveViaSystemDrawing_Jpg()
        {
            using (var stream = new MemoryStream(TestImageBuffer))
            {
                var a = PixImage.Create(stream);

                using (var store = new MemoryStream())
                {
                    var success = a.SaveViaSystemDrawing(store, PixFileFormat.Jpeg, PixSaveOptions.Default, 90);
                    Assert.IsTrue(success);
                    store.Seek(0, SeekOrigin.Begin);
                    var b = PixImage.Create(store);
                    Assert.IsTrue(a.Size == b.Size);
                }
            }
        }
Beispiel #17
0
        public static void SaveAndUpload(PixImage image, bool uploadToServer, string tags = null)
        {
            // need to clone the image; original will be disposed afterwards
            Task.Factory.StartNew(delegate
            {
                // 1. save file locally
                SaveToDesktop(image);

                // 2. upload
                if (uploadToServer)
                {
                    UploadImageToServer(image, tags);
                }
            }
                                  //, Kernel.TaskManager.CpuBoundLowPriority
                                  );
        }
        static PixImage RenderSimple(Scene scene, int width, int height, Trafo3d view, Trafo3d proj, Dictionary <uint, EmbreeIndexedGeometry> geos)
        {
            var img = new PixImage <byte>(width, height, 4);
            var mtx = img.GetMatrix <C4b>();

            var viewProj    = view * proj;
            var invViewProj = viewProj.Backward;

            RTCFilterFunction filter = null;

            //unsafe
            //{
            //    filter = new RTCFilterFunction(ptr =>
            //    {
            //        //((uint*)ptr->valid)[0] = 0;
            //    });
            //}

            for (int i = 0; i < 20; i++)
            {
                var sw = Stopwatch.StartNew();
                Parallel.For(0, height, new ParallelOptions(), y =>
                {
                    for (int x = 0; x < width; x++)
                    {
                        var uv = (new V2d(x, y) + 0.5) / new V2d(width, height);

                        var ray = GetCameraRay(uv, invViewProj);

                        var color = GetColor(scene, ray, geos, filter);

                        mtx[x, y] = color;
                    }
                });
                var rayCount      = width * height;
                var raysPerSecond = rayCount / sw.Elapsed.TotalSeconds / 1e6;
                Report.Line("{0:0.00}MRay/s", raysPerSecond);
            }

            return(img);
        }
Beispiel #19
0
        /// <summary>
        /// Starts the image upload and returns an image key which
        /// is generated by the server to identify the image.
        /// </summary>
        public static string UploadImageToServer(PixImage image, string tags = null)
        {
            try
            {
                using (var stream = new MemoryStream())
                {
                    image.SaveAsImage(stream, PixFileFormat.Png);

                    tags = tags ?? Environment.UserName + " " + Assembly.GetEntryAssembly().GetName().Name;
                    tags = "aardvark.rendering " + tags;

                    return(UploadImageDataToServer(stream, tags));
                }
            }
            catch (Exception e)
            {
                // fail (almost) silently if upload does not work
                Report.Line("screenshot upload failed: {0}", e.ToString());
                return(null);
            }
        }
Beispiel #20
0
        static void Benchmark()
        {
            var device = new Device();

            Report.Line("Using {0} Threads", device.NumThreads);

            var img = new PixImage <float>(1, 1, 3);
            var avg = new AverageWindow(100);
            var sw  = new Stopwatch();

            for (int i = 0; i < 100; i++)
            {
                sw.Restart();
                device.Denoise(img);
                avg.Insert(sw.Elapsed.TotalMilliseconds);
            }

            Report.Line("Avg Time: {0:0.000}ms", avg.Value);

            device.Dispose();
        }
Beispiel #21
0
        public static void LinearRampDemo(string dir)
        {
            Report.BeginTimed("linear ramp demo");
            var width     = 1920;
            var height    = 1080;
            var barHeight = height / 4;

            var line = new byte[width].SetByIndex(
                i => Col.ByteFromDouble((double)i / (double)(width - 1)));

            // write an image with linear red, green, blue, and gray ramps
            var linearImage = new PixImage <byte>(Col.Format.RGB, new V2i(width, height));
            var linVol      = linearImage.Volume;

            linVol.SubVolume(0, 0, 0, width, barHeight, 1).AsMatrixWindow().SetByCoord((x, y) => line[x]);
            linVol.SubVolume(0, barHeight, 1, width, barHeight, 1).AsMatrixWindow().SetByCoord((x, y) => line[x]);
            linVol.SubVolume(0, 2 * barHeight, 2, width, barHeight, 1).AsMatrixWindow().SetByCoord((x, y) => line[x]);
            linVol.SubVolume(0, 3 * barHeight, 0, width, barHeight, 3).SetByCoord((x, y, c) => line[x]);

            linearImage.SaveAsImage(Path.Combine(dir, "linear-ramp.tiff"));
            Report.End();
        }
Beispiel #22
0
        /// <summary>
        /// Creates Images of an optical illusion that tricks the mind into
        /// seeing more different colors (4) than are actually present in the
        /// image (3).
        /// </summary>
        public static PixImage <byte> CreateHowManyColorsIllusion(int size, bool parallel = true)
        {
            var scale = 1024.0 / size;
            var delta = 0.5 * (double)(size - 1);

            var pixImage = new PixImage <byte>(size, size, 3);

            var colorMatrix = pixImage.GetMatrix <C3b>();

            var orange    = new C3b(255, 150, 0);
            var magenta   = new C3b(255, 0, 255);
            var bluegreen = new C3b(0, 255, 150);
            Func <long, long, C3b> pixelFun = (x, y) =>
            {
                var xd = scale * (x - delta); var yd = scale * (y - delta);
                var r   = Fun.Sqrt(xd * xd + yd * yd);
                var phi = Fun.Atan2(yd, xd);
                var lp1 = phi / Constant.PiTimesFour;
                var lp2 = phi / Constant.Pi; // TimesTwo;
                var lr  = Fun.Log(r) / Constant.E;
                var p1  = Fun.Frac(0.05 + 4 * (lr - lp1));
                var p2  = Fun.Frac(96 * (lr + lp2)); // 64
                return(p2 < 0.5
                    ? (p1 >= 0.0 && p1 < 0.25 ? bluegreen : orange)
                    : (p1 >= 0.5 && p1 < 0.75 ? bluegreen : magenta));
            };

            if (parallel)
            {
                colorMatrix.SetByCoordParallelY(pixelFun);
            }
            else
            {
                colorMatrix.SetByCoord(pixelFun);
            }

            return(pixImage);
        }
        /// <summary>
        /// Denoises the input image with optinal albedo and normal images to the output image buffer
        /// inputScale: a value of 1 should represent 100cd/m² -> inputScale can be used to setup this (NaN for auto calculation)
        /// </summary>
        public void Denoise(PixImage <float> color, PixImage <float> albedo, PixImage <float> normal, PixImage <float> outImage, float inputScale = float.NaN)
        {
            if (color.ChannelCount < 3 || color.ChannelCount > 4)
            {
                throw new ArgumentException("Image must have 3 or 4 channels");
            }
            if (albedo != null && (albedo.ChannelCount < 3 || albedo.ChannelCount > 4))
            {
                throw new ArgumentException("Image must have 3 or 4 channels");
            }
            if (normal != null && (normal.ChannelCount < 3 || normal.ChannelCount > 4))
            {
                throw new ArgumentException("Image must have 3 or 4 channels");
            }
            if (outImage.ChannelCount < 3 || outImage.ChannelCount > 4)
            {
                throw new ArgumentException("Output image must have 3 or 4 channels");
            }

            var width  = color.Size.X;
            var height = color.Size.Y;

            if (albedo != null && (albedo.Size.X != width || albedo.Size.Y != height))
            {
                throw new ArgumentException("Albedo image size does not match with input");
            }
            if (normal != null && (normal.Size.X != width || normal.Size.Y != height))
            {
                throw new ArgumentException("Normal image size does not match with input");
            }
            if (outImage.Size.X != width || outImage.Size.Y != height)
            {
                throw new ArgumentException("Ouput image size does not match with input");
            }

            // Oidn only supports 3 channel images -> use pixelStride
            var pixelStride       = color.ChannelCount * 4;
            var outPixelStride    = outImage.ChannelCount * 4;
            var albedoPixelStride = albedo?.ChannelCount * 4 ?? 0;
            var normalPixelStride = normal?.ChannelCount * 4 ?? 0;

            var colorPtr  = GCHandle.Alloc(color.Data, GCHandleType.Pinned);
            var albedoPtr = albedo != null?GCHandle.Alloc(albedo.Data, GCHandleType.Pinned) : default;

            var normalPtr = normal != null?GCHandle.Alloc(normal.Data, GCHandleType.Pinned) : default;

            var outputPtr = GCHandle.Alloc(outImage.Data, GCHandleType.Pinned);

            // Create a denoising filter
            var filter = OidnAPI.oidnNewFilter(m_device, "RT"); // generic ray tracing filter

            OidnAPI.oidnSetSharedFilterImage(filter, "color", colorPtr.AddrOfPinnedObject(), ImageFormat.Float3, width, height, 0, pixelStride, pixelStride * width);
            if (albedo != null)
            {
                OidnAPI.oidnSetSharedFilterImage(filter, "albedo", albedoPtr.AddrOfPinnedObject(), ImageFormat.Float3, width, height, 0, albedoPixelStride, albedoPixelStride * width);
            }
            if (normal != null)
            {
                OidnAPI.oidnSetSharedFilterImage(filter, "normal", normalPtr.AddrOfPinnedObject(), ImageFormat.Float3, width, height, 0, normalPixelStride, normalPixelStride * width);
            }
            OidnAPI.oidnSetSharedFilterImage(filter, "output", outputPtr.AddrOfPinnedObject(), ImageFormat.Float3, width, height, 0, outPixelStride, outPixelStride * width);
            OidnAPI.oidnSetFilter1b(filter, "hdr", true); // image is HDR
            if (!inputScale.IsNaN())
            {
                OidnAPI.oidnSetFilter1f(filter, "inputScale", inputScale);
            }
            OidnAPI.oidnCommitFilter(filter);

            // Filter the image
            OidnAPI.oidnExecuteFilter(filter);

            colorPtr.Free();
            if (albedo != null)
            {
                albedoPtr.Free();
            }
            if (normal != null)
            {
                normalPtr.Free();
            }
            outputPtr.Free();

            // Check for errors
            if (OidnAPI.oidnGetDeviceError(m_device, out var errorMessage) != Error.None)
            {
                Report.Warn("Error: {0}", errorMessage);
            }

            // Cleanup
            OidnAPI.oidnReleaseFilter(filter);
        }
Beispiel #24
0
 public static void SaveToFileInPath(PixImage image, string path)
 {
     SaveToFile(image, CreateScreenShotFilePath(path));
 }
Beispiel #25
0
 /// <summary>
 /// Saves the image to a file on the desktop.
 /// </summary>
 public static void SaveToDesktop(PixImage image)
 {
     SaveToFile(image, CreateImageDesktopFilename());
 }
Beispiel #26
0
        public static void VariousDemos(string dir)
        {
            bool alternative = true;

            // WriteLinearRampImage();
            // Interpolation();

            Report.BeginTimed("various PixImage demos");
            // NOTE: in the following comments a byte image is an image that uses a
            // byte for each channel of each pixel, a float image is an image that uses
            // a float for each channel of each pixel.

            var colorImage = CreateHowManyColorsIllusion(1024);

            // scaling an image
            var scaledColorImage = new PixImage <byte>(1280, 800, 3);

            scaledColorImage.GetMatrix <C3b>().SetScaledCubic(colorImage.GetMatrix <C3b>());
            scaledColorImage.SaveAsImage(Path.Combine(dir, "v-scaled-image.png"));

            // For shrinking images, interpoation of image values is not the optimal
            // resampling filter. Here BSpline3 or BSpline5 approximation can be used
            // which are 3rd order or 5th order approximations of a Gauss filter.
            var shrunkColorImage = new PixImage <byte>(512, 512, 3);

            shrunkColorImage.GetMatrix <C3b>().SetScaledBSpline5(colorImage.GetMatrix <C3b>());
            shrunkColorImage.SaveAsImage(Path.Combine(dir, "v-shrunk-image.png"));

            var largeColorImage = new PixImage <byte>(4096, 4096, 3);

            largeColorImage.GetMatrix <C3b>().SetScaledLanczos(colorImage.GetMatrix <C3b>());
            largeColorImage.SaveAsImage(Path.Combine(dir, "v-large-lanczos-image.png"));



            var scaledColorImage2 = new PixImage <byte>(1280, 800, 3);

            scaledColorImage2.GetMatrix <C3b>().SetScaledLanczos(colorImage.GetMatrix <C3b>());
            scaledColorImage.SaveAsImage(Path.Combine(dir, "v-scaled-lanczos-image.png"));

            var smallColorImage = CreateHowManyColorsIllusion(256);

            var nearestScaledImage = new PixImage <byte>(1024, 768, 3);

            nearestScaledImage.GetMatrix <C3b>().SetScaledNearest(smallColorImage.GetMatrix <C3b>());
            nearestScaledImage.SaveAsImage(Path.Combine(dir, "v-scaled-nearest-image.png"));


            // writing a color png image
            colorImage.SaveAsImage(Path.Combine(dir, "v-color-image.png"));

            var grayImage = colorImage.ToGrayscalePixImage();


            // scaling a grayscale image
            var scaledGrayImage = new PixImage <byte>(1280, 800, 1);

            scaledGrayImage.Matrix.SetScaledLanczos(grayImage.Matrix);

            scaledGrayImage.SaveAsImage(Path.Combine(dir, "v-scaled-gray-image.png"));

            // for grayscale and black/white images the Matrix property works
            grayImage.Matrix.SetLineY(16, 0, 100, 0);

            // writing a grayscale png image
            grayImage.SaveAsImage(Path.Combine(dir, "v-gray-image.png"));


            var gray2colorImage = grayImage.ToPixImage <byte>(Col.Format.BGR);

            // writing grayxcal image as a color image
            gray2colorImage.SaveAsImage(Path.Combine(dir, "v-gray2color-image.png"));

            // loading a 8-bit per channel color image
            var byteImg = new PixImage <byte>(Path.Combine(dir, "v-color-image.png"));

            //var byteImg2 = byteImg.Scaled(0.5);
            //byteImg2.SaveAsImage(Path.Combine(dir, "v-color-2.png"));
            //var byteImg4 = byteImg2.Scaled(0.5);
            //byteImg4.SaveAsImage(Path.Combine(dir, "v-color-4.png"));
            //var byteImg8 = byteImg4.Scaled(0.5);
            //byteImg8.SaveAsImage(Path.Combine(dir, "r-color-8.png"));

            // retrieving channel matrices from an rgb image
            var rc = byteImg.GetChannel(Col.Channel.Red);
            var gc = byteImg.GetChannel(Col.Channel.Green);
            var bc = byteImg.GetChannel(Col.Channel.Blue);

            // convert 8bit/channel rgb image to 16bit/channel image
            // var ushortImage = byteImg.ToPixImage<ushort>();

            // ushortImage.Rotated(30 * Constant.RadiansPerDegree, false)
            //            .SaveAsImage(Path.Combine(odir, "rotated_30_rgb16.png"));

            // save 16bit/channel rgb image.
            // ushortImage.SaveAsImage(Path.Combine(odir, "rgb8_to_rgb16.tif"));

            // load 16bit/channel rgb image
            // var ushortImage2 = new PixImage<ushort>(Path.Combine(odir, "rgb8_to_rgb16.tif"));

            // save again as 8bit/channel rgb image
            // ushortImage2.ToPixImage<byte>().SaveAsImage(Path.Combine(odir, "rgb8_to_rgb16_to_rgb8.tif"));

            // building a new rgb image from channel matrices
            var newImg = new PixImage <byte>(rc, gc, bc);

            // writing an 8-bit per channel png image
            newImg.SaveAsImage(Path.Combine(dir, "v-recombined-color.png"), PixFileFormat.Png,
                               options: PixSaveOptions.Default
                               | PixSaveOptions.UseStorageService
                               | PixSaveOptions.UseChunkedStream);

            //byteImg.Rotated(60.0 * Constant.RadiansPerDegree)
            //        .SaveAsImage(Path.Combine(dir, "v-rotated-60-resized.png"));

            //byteImg.Rotated(90.0 * Constant.RadiansPerDegree)
            //        .SaveAsImage(Path.Combine(dir, "v-rotated-90-resized.png"));

            //byteImg.Volume.Transformed(ImageTrafo.Rot90).ToPixImage()
            //        .SaveAsImage(Path.Combine(odir, "rotated_90_csharp_rgb8.png"));

            //byteImg.Rotated(180.0 * Constant.RadiansPerDegree)
            //        .SaveAsImage(Path.Combine(dir, "v-rotated-180-resized.png"));

            //byteImg.Volume.Transformed(ImageTrafo.Rot180).ToPixImage()
            //        .SaveAsImage(Path.Combine(odir, "rotated_180_csharp_rgb8.png"));

            //byteImg.Rotated(270.0 * Constant.RadiansPerDegree)
            //        .SaveAsImage(Path.Combine(dir, "v-rotated-270-resized.png"));

            //byteImg.Volume.Transformed(ImageTrafo.Rot270).ToPixImage()
            //        .SaveAsImage(Path.Combine(odir, "rotated_270_csharp_rgb8.png"));

            // loading an 8-bit per channel rgb image directly as a float image
            var floatImg = new PixImage <float>(Path.Combine(dir, "v-color-image.png"));

            // converting a float image to a byte image
            var floatToByteImg = floatImg.ToPixImage <byte>();

            // saving the converted image in png format
            floatToByteImg.SaveAsImage(Path.Combine(dir, "v-byte2float2byte-color.png"));

            // color conversion to linear response
            var linearFloatImg = floatImg.Copy <C3f>(Col.LinearSRGBFromSRGB);

            // converting the linear float image to a byte image and saving it in png format
            linearFloatImg.ToPixImage <byte>().SaveAsImage(Path.Combine(dir, "v-linear-color.png"));

            // loading a byte image
            var bImg = new PixImage <byte>(Path.Combine(dir, "v-color-image.png"));

            byte threshold = 2;

            var isSame = byteImg.Volume.InnerProduct(
                bImg.Volume, (b1, b2) => Fun.Abs(b2 - b1) < threshold,
                true, (equal, pixEqual) => equal && pixEqual, equal => !equal);



            // replacing a border of 50 pixels by replicating the 1-pixel frame inside
            // the border outwards
            bImg.Volume.ReplicateBorder(new Border2l(50));

            // acessing pixels of a byte image as C3b's
            var c3bmatrix = bImg.GetMatrix <C3b>();

            // var copiedMatrix = c3bmatrix.Copy();

            var newC3fImage = c3bmatrix.ToPixImage <float>();

            // setting a region in the matrix
            c3bmatrix.SetRectangleFilled(48, 48, 52, 52, C3b.Black); // min x, min y, max x, max y

            if (alternative)
            {
                // this is equivalent to:
                c3bmatrix.SubMatrix(48, 48, 5, 5).Set(C3b.Black); // start x, start y, size x, size y
            }

            // accessing a single pixel of the matrix
            c3bmatrix[50, 50] = C3b.VRVisGreen;

            var size = c3bmatrix.Size;

            // draw a bresenham line
            c3bmatrix.SetLine(size.X - 50, 50, 50, size.Y - 50, C3b.Blue);

            // draw a bresenham circle
            c3bmatrix.SetCircle(size.X / 2, size.Y / 2, 50, C3b.Yellow);

            c3bmatrix.SetCircleFilled((size.X * 3) / 4, (size.Y * 3) / 4, 50, C3b.Yellow);
            c3bmatrix.SetCircleFilled(25, 25, 75, C3b.Yellow);


            var cx = size.X / 2; var cy = size.Y / 2;

            for (int i = 0; i < 36; i++)
            {
                var alpha = i * 2 * Constant.Pi / 36;
                var dx    = Fun.Cos(alpha);
                var dy    = Fun.Sin(alpha);

                c3bmatrix.SetLineAllTouchedRaw(cx + 64 * dx, cy + 64 * dy, cx + 128 * dx, cy + 128 * dy,
                                               C3b.Yellow);
            }



            // writing the image with the replicated border as a png
            bImg.SaveAsImage(Path.Combine(dir, "v-border-drawing.png"));

            Report.End();
        }
Beispiel #27
0
        /// <summary>
        /// Perform image resampling in software. Shows how to use higher order
        /// resampling (e.g. Lanczos or Bicubic) on matrices. This is not a very
        /// fast implementation, but it works on Matrices of arbitrary type!
        /// </summary>
        public static void ResampleDemo(string dir)
        {
            Report.BeginTimed("resample example");
            var inImg = CreateHowManyColorsIllusion(300);
            var inMat = inImg.GetMatrix <C3b>();

            // enlarge by a factor of Pi to see what happens
            double scale = 1.0 / Constant.Pi;
            double shift = -13.0;

            var outImg0 = new PixImage <byte>(1024, 1024, 3);
            var outMat0 = outImg0.GetMatrix <C3b>();
            var outImg1 = new PixImage <byte>(1024, 1024, 3);
            var outMat1 = outImg1.GetMatrix <C3b>();
            var outImg2 = new PixImage <byte>(1024, 1024, 3);
            var outMat2 = outImg2.GetMatrix <C3b>();
            var outImg3 = new PixImage <byte>(1024, 1024, 3);
            var outMat3 = outImg3.GetMatrix <C3b>();

            // create the cubic weighting function. Parameter a=-0.5 results in the cubic Hermite spline.
            var hermiteSpline = Fun.CreateCubicTup4f(-0.5);

            outMat0.ForeachIndex((x, y, i) =>
            {
                /// Note: LinComRawF in x direction results in a byte color (range 0-255) stored
                /// in a C3f. The second Col.LinCom for the y direction does not perform any additional
                /// scaling, thus we need to map the "ByteInFloat" color back to a byte color at the
                /// end (this perfoms clamping). Tensor.Tensor.Index6SamplesClamped clamps to the border
                /// region and allows any double pixel address.
                outMat0[i] = inMat.Sample36(x * scale + shift, y * scale + shift,
                                            Fun.Lanczos3f, Fun.Lanczos3f,
                                            Col.LinComRawF, Col.LinCom,
                                            Tensor.Index6SamplesClamped, Tensor.Index6SamplesClamped)
                             .Map(Col.ByteFromByteInFloatClamped);

                /// Note: LinComRawF in x direction results in a byte color (range 0-255) stored
                /// in a C3f. The second Col.LinCom for the y direction does not perform any additional
                /// scaling, thus we need to map the "ByteInFloat" color back to a byte color at the
                /// end (this perfoms clamping). Tensor.Index4SamplesClamped clamps to the border
                /// region and allows any double pixel address.
                outMat1[i] = inMat.Sample16(x * scale + shift, y * scale + shift,
                                            hermiteSpline, hermiteSpline,
                                            Col.LinComRawF, Col.LinCom,
                                            Tensor.Index4SamplesClamped, Tensor.Index4SamplesClamped)
                             .Map(Col.ByteFromByteInFloatClamped);


                /// Note here the two Col.LinCom calls perform the clamping immediately. Thus we have
                /// Five clamping calls on each sample: 4 on each x-line, and one in the final
                /// y-interpolation.
                /// Here we have cyclic border handling. Note that Tensor.Index4SamplesCyclic1 only
                /// handles one cycle at each side (minus some border pixels), so the addressable
                /// range is not quite 3x3 times the size of the original image.
                outMat2[i] = inMat.Sample16(x * scale + shift, y * scale + shift,
                                            hermiteSpline, hermiteSpline,
                                            Col.LinCom, Col.LinCom,
                                            Tensor.Index4SamplesCyclic1, Tensor.Index4SamplesCyclic1);

                outMat3[i] = inMat.Sample4Clamped(x * scale + shift, y * scale + shift, Fun.Lerp, Fun.Lerp);
                //.Map(Col.ByteFromByteInDoubleClamped);
            });

            outImg0.SaveAsImage(Path.Combine(dir, "resample-36clamped.tif"));
            outImg1.SaveAsImage(Path.Combine(dir, "resample-16clamped.tif"));
            outImg2.SaveAsImage(Path.Combine(dir, "resample-d16cyclic.tif"));
            outImg3.SaveAsImage(Path.Combine(dir, "resample-4clamped.tif"));
            Report.End();
        }
Beispiel #28
0
 /// <summary>
 /// Saves the image to a given filename.
 /// </summary>
 public static void SaveToFile(PixImage image, string fileName)
 {
     image.SaveAsImage(fileName, PixFileFormat.Png);
     Report.Line(5, "saved screenshot: {0}", fileName);
 }
Beispiel #29
0
        private static XElement BuildCompleteMetaInfo(XElement metaDataFromForm, string imageKey, PixImage image)
        {
            string[] parts    = imageKey.Split('\\');
            string   fileName = parts[3];

            var created       = DateTime.Now;
            var thumbFileName = fileName + ".thumb.jpg";
            //var infoFileName = fileName + ".xml";
            var size = image.Size;

            var metaInfo =
                new XElement("ScreenshotInfo",
                             new XAttribute("Created", created.ToString()),
                             new XElement("FileName", fileName),
                             new XElement("ThumbFileName", thumbFileName),
                             new XElement("Size", size.ToString()),
                             new XElement("Tag", "",
                                          new XAttribute("Created", created.ToString())),
                             new XElement("Tag", metaDataFromForm.Element("Tag").Value,
                                          new XAttribute("Created", created.ToString())),
                             new XElement("Kategorie", "",
                                          new XAttribute("Created", created.ToString())),
                             new XElement("Kategorie", metaDataFromForm.Element("Kategorie").Value,
                                          new XAttribute("Created", created.ToString())),
                             new XElement("Comment", "Screenshot erstellt",
                                          new XAttribute("Created", created.ToString())),
                             new XElement("Comment", metaDataFromForm.Element("Comment").Value,
                                          new XAttribute("Created", created.ToString()))
                             );

            return(metaInfo);
        }
        static void Init()
        {
            PixImage <byte> .SetScaledFun(Scaled);

            //PixImage<byte>.SetScaledFun(Aardvark.VRVis.TensorExtensions.Scaled);
        }