public void TestSwitch()
        {
            // switch was added in libvips 8.9.
            Skip.IfNot(NetVips.AtLeastLibvips(8, 9), "requires libvips >= 8.9");

            var x = Image.Grey(256, 256, uchar: true);

            // slice into two at 128, we should get 50% of pixels in each half
            var index = Image.Switch(x < 128, x >= 128);

            Assert.Equal(0.5, index.Avg());

            // slice into four
            index = Image.Switch(
                x < 64,
                x >= 64 && x < 128,
                x >= 128 && x < 192,
                x >= 192
                );
            Assert.Equal(1.5, index.Avg());

            // no match should return n + 1
            index = Image.Switch(x.Equal(1000), x.Equal(2000));
            Assert.Equal(2, index.Avg());
        }
        public void TestCase()
        {
            // case was added in libvips 8.9.
            Skip.IfNot(NetVips.AtLeastLibvips(8, 9), "requires libvips >= 8.9");

            var x = Image.Grey(256, 256, uchar: true);

            // slice into two at 128, we should get 50% of pixels in each half
            var index = Image.Switch(x < 128, x >= 128);
            var y     = index.Case(10, 20);

            Assert.Equal(15, y.Avg());

            // slice into four
            index = Image.Switch(
                x < 64,
                x >= 64 && x < 128,
                x >= 128 && x < 192,
                x >= 192
                );
            Assert.Equal(25, index.Case(10, 20, 30, 40).Avg());

            // values over N should use the last value
            Assert.Equal(22.5, index.Case(10, 20, 30).Avg());
        }
Exemple #3
0
        public void TestMatrixinvert()
        {
            // matrixinvert was added in libvips 8.10.
            Skip.IfNot(NetVips.AtLeastLibvips(8, 10), "requires libvips >= 8.10");

            // 4x4 matrix to check if PLU decomposition works
            var mat = Image.NewFromArray(new[, ]
            {
                { 4, 0, 0, 0 },
                { 0, 0, 2, 0 },
                { 0, 1, 2, 0 },
                { 1, 0, 0, 1 }
            });
            var im = mat.Matrixinvert();

            Assert.Equal(4, im.Width);
            Assert.Equal(4, im.Height);
            Assert.Equal(1, im.Bands);
            Assert.Equal(Enums.BandFormat.Double, im.Format);

            var p = im[0, 0];

            Assert.Equal(0.25, p[0]);
            p = im[3, 3];
            Assert.Equal(1.0, p[0]);
        }
 public GenerateImageClass()
 {
     if (NetVips.AtLeastLibvips(8, 9))
     {
         _gTypeToCSharpDict.Add(GValue.SourceType, "Source");
         _gTypeToCSharpDict.Add(GValue.TargetType, "Target");
     }
 }
Exemple #5
0
        public void TestGetFields()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 5), "requires libvips >= 8.5");

            var im     = Image.Black(10, 10);
            var fields = im.GetFields();

            // we might add more fields later
            Assert.True(fields.Length > 10);

            Assert.Equal("width", fields[0]);
        }
Exemple #6
0
        public void TestGetSuffixes()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 8), "requires libvips >= 8.8");

            var suffixes = NetVips.GetSuffixes();

            // vips supports these file types by default
            // (without being dependent on external dependencies):
            // - Native file format (`*.v`, `*.vips`).
            // - PPM images (`*.ppm`, `*.pgm`, `*.pbm`, `*.pfm`).
            // - Analyze images (`*.hdr`).
            Assert.True(suffixes.Length >= 7);
        }
Exemple #7
0
        public void TestCmyk()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 8), "requires libvips >= 8.8");

            // even without lcms, we should have a working approximation
            var test = Image.NewFromFile(Helper.JpegFile);
            var im   = test.Colourspace(Enums.Interpretation.Cmyk).Colourspace(Enums.Interpretation.Srgb);

            var before = test[582, 210];
            var after  = im[582, 210];

            Helper.AssertAlmostEqualObjects(before, after, 10);
        }
Exemple #8
0
        public void TestGifLoad()
        {
            Skip.IfNot(Helper.Have("gifload") && File.Exists(Helper.GifFile), "no gif support, skipping test");

            void GifValid(Image im)
            {
                var a = im[10, 10];

                Assert.Equal(new double[] { 33 }, a);
                Assert.Equal(159, im.Width);
                Assert.Equal(203, im.Height);
                Assert.Equal(1, im.Bands);
            }

            FileLoader("gifload", Helper.GifFile, GifValid);
            BufferLoader("gifload_buffer", Helper.GifFile, GifValid);

            // 'n' param added in 8.5
            if (NetVips.AtLeastLibvips(8, 5))
            {
                var x1 = Image.NewFromFile(Helper.GifAnimFile);
                var x2 = Image.NewFromFile(Helper.GifAnimFile, kwargs: new VOption
                {
                    { "n", 2 }
                });
                Assert.Equal(2 * x1.Height, x2.Height);
                var pageHeight = x2.Get("page-height");
                Assert.Equal(x1.Height, pageHeight);

                x2 = Image.NewFromFile(Helper.GifAnimFile, kwargs: new VOption
                {
                    { "n", -1 }
                });
                Assert.Equal(5 * x1.Height, x2.Height);

                // delay metadata was added in libvips 8.9
                if (NetVips.AtLeastLibvips(8, 9))
                {
                    // our test gif has delay 0 for the first frame set in error
                    Assert.Equal(new[] { 0, 50, 50, 50, 50 }, x2.Get("delay"));
                }

                x2 = Image.NewFromFile(Helper.GifAnimFile, kwargs: new VOption
                {
                    { "page", 1 },
                    { "n", -1 }
                });
                Assert.Equal(4 * x1.Height, x2.Height);
            }
        }
        public void TestTanh()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 12), "requires libvips >= 8.12");

            dynamic Tanh(dynamic x)
            {
                if (x is Image image)
                {
                    return(image.Tanh());
                }

                return(Math.Tanh(x));
            }

            RunUnary(_allImages, Tanh, Helper.NonComplexFormats);
        }
Exemple #10
0
        public void TestMagickSave()
        {
            Skip.IfNot(Helper.Have("magicksave"), "no magick support, skipping test");

            // save to a file and load again ... we can't use SaveLoadFile since
            // we want to make sure we use magickload/save
            // don't use BMP - GraphicsMagick always adds an alpha
            // don't use TIF - IM7 will save as 16-bit
            var filename = Helper.GetTemporaryFile(_tempDir, ".jpg");

            _colour.Magicksave(filename);
            var x = Image.Magickload(filename);

            Assert.Equal(_colour.Width, x.Width);
            Assert.Equal(_colour.Height, x.Height);
            Assert.Equal(_colour.Bands, x.Bands);
            Assert.Equal(_colour.Height, x.Height);

            var maxDiff = (_colour - x).Abs().Max();

            Assert.True(maxDiff <= 60);

            SaveLoadBuffer("magicksave_buffer", "magickload_buffer", _colour, 60, new VOption
            {
                { "format", "JPG" }
            });

            // try an animation
            if (Helper.Have("gifload"))
            {
                var x1 = Image.NewFromFile(Helper.GifAnimFile, kwargs: new VOption
                {
                    { "n", -1 }
                });
                var w1 = x1.MagicksaveBuffer(format: "GIF");
                var x2 = Image.NewFromBuffer(w1, kwargs: new VOption
                {
                    { "n", -1 }
                });

                var delayName = NetVips.AtLeastLibvips(8, 9) ? "delay" : "gif-delay";
                Assert.Equal(x2.Get(delayName), x1.Get(delayName));
                Assert.Equal(x2.Get("page-height"), x1.Get("page-height"));
                // magicks vary in how they handle this ... just pray we are close
                Assert.True(Math.Abs((int)x1.Get("gif-loop") - (int)x2.Get("gif-loop")) < 5);
            }
        }
Exemple #11
0
        public void TestAtan2()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 12), "requires libvips >= 8.12");

            dynamic Atan2(dynamic x, dynamic y)
            {
                if (x is Image left)
                {
                    return(left.Atan2(y));
                }

                return(Math.Atan2(x[0], y[0]) * (180.0 / Math.PI));
            }

            var im = (Image.Black(100, 100) + new[] { 0, 1, 2 }) / 3.0;

            RunBinary(im.Bandsplit(), Atan2, Helper.NonComplexFormats);
        }
Exemple #12
0
        public void TestAtanh()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 12), "requires libvips >= 8.12");

            dynamic Atanh(dynamic x)
            {
                if (x is Image image)
                {
                    return(image.Atanh());
                }

                return(Math.Atanh(x));
            }

            var im = (Image.Black(100, 100) + new[] { 0, 1, 2 }) / 3.0;

            RunUnary(new[] { im }, Atanh, Helper.NonComplexFormats);
        }
Exemple #13
0
        public void TestRegion()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 8), "requires libvips >= 8.8");

            var im     = Image.Black(100, 100);
            var region = Region.New(im);
            var data   = region.Fetch(0, 0, 10, 10);

            Assert.Equal(10, region.Width);
            Assert.Equal(10, region.Height);
            Assert.True(data.Length == 100);
            Assert.True(data.All(p => p == 0));

            data = region.Fetch(0, 0, 20, 10);

            Assert.Equal(20, region.Width);
            Assert.Equal(10, region.Height);
            Assert.True(data.Length == 200);
            Assert.True(data.All(p => p == 0));
        }
        public void TestHistLocal()
        {
            var im = Image.NewFromFile(Helper.JpegFile);

            var im2 = im.HistLocal(10, 10);

            Assert.Equal(im.Width, im2.Width);
            Assert.Equal(im.Height, im2.Height);

            Assert.True(im.Avg() < im2.Avg());
            Assert.True(im.Deviate() < im2.Deviate());

            if (NetVips.AtLeastLibvips(8, 5))
            {
                var im3 = im.HistLocal(10, 10, maxSlope: 3);
                Assert.Equal(im.Width, im3.Width);
                Assert.Equal(im.Height, im3.Height);

                Assert.True(im3.Deviate() < im2.Deviate());
            }
        }
Exemple #15
0
        public void TestThumbnail()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 5), "requires libvips >= 8.5");

            var im = Image.Thumbnail(Helper.JpegFile, 100);

            Assert.Equal(100, im.Width);
            Assert.Equal(3, im.Bands);

            // the average shouldn't move too much
            var imOrig = Image.NewFromFile(Helper.JpegFile);

            Assert.True(Math.Abs(imOrig.Avg() - im.Avg()) < 1);

            // make sure we always get the right width
            for (var width = 1000; width >= 1; width -= 13)
            {
                im = Image.Thumbnail(Helper.JpegFile, width);
                Assert.Equal(width, im.Width);
            }

            // should fit one of width or height
            im = Image.Thumbnail(Helper.JpegFile, 100, height: 300);
            Assert.Equal(100, im.Width);
            Assert.NotEqual(300, im.Height);
            im = Image.Thumbnail(Helper.JpegFile, 300, height: 100);
            Assert.NotEqual(300, im.Width);
            Assert.Equal(100, im.Height);

            // with @crop, should fit both width and height
            im = Image.Thumbnail(Helper.JpegFile, 100, height: 300, crop: "centre");
            Assert.Equal(100, im.Width);
            Assert.Equal(300, im.Height);

            var im1 = Image.Thumbnail(Helper.JpegFile, 100);
            var buf = File.ReadAllBytes(Helper.JpegFile);
            var im2 = Image.ThumbnailBuffer(buf, 100);

            Assert.True(Math.Abs(im1.Avg() - im2.Avg()) < 1);
        }
Exemple #16
0
        public void TestOpenexrLoad()
        {
            Skip.IfNot(Helper.Have("openexrload") && File.Exists(Helper.ExrFile), "no openexr support, skipping test");

            void ExrValid(Image im)
            {
                var a = im[10, 10];

                Helper.AssertAlmostEqualObjects(new[]
                {
                    0.124512,
                    0.159668,
                    0.040375,
                    // OpenEXR alpha is scaled to 0 - 255 in libvips 8.7+
                    NetVips.AtLeastLibvips(8, 7) ? 255 : 1.0
                }, a, 0.00001);
                Assert.Equal(610, im.Width);
                Assert.Equal(406, im.Height);
                Assert.Equal(4, im.Bands);
            }

            FileLoader("openexrload", Helper.ExrFile, ExrValid);
        }
Exemple #17
0
        public void TestText()
        {
            Skip.IfNot(Helper.Have("text"), "no text in this vips, skipping test");

            var im = Image.Text("Hello, world!", dpi: 300);

            Assert.True(im.Width > 10);
            Assert.True(im.Height > 10);
            Assert.Equal(1, im.Bands);
            Assert.Equal(Enums.BandFormat.Uchar, im.Format);
            Assert.Equal(255, im.Max());
            Assert.Equal(0, im.Min());

            if (NetVips.AtLeastLibvips(8, 9))
            {
                // test autofit
                im = Image.Text("Hello, world!", width: 500, height: 500);

                // quite a large threshold, since we need to work with a huge range of
                // text rendering systems
                Assert.True(Math.Abs(im.Width - 500) < 50);
            }
        }
Exemple #18
0
        public void TestPdfLoad()
        {
            Skip.IfNot(Helper.Have("pdfload") && File.Exists(Helper.PdfFile), "no pdf support, skipping test");

            void PdfValid(Image im)
            {
                var a = im[10, 10];

                Assert.Equal(new double[] { 35, 31, 32, 255 }, a);

                // New sizing rules in libvips 8.8+, see:
                // https://github.com/libvips/libvips/commit/29d29533d45848ecc12a3c50c39c26c835458a61
                Assert.Equal(NetVips.AtLeastLibvips(8, 8) ? 1134 : 1133, im.Width);
                Assert.Equal(680, im.Height);
                Assert.Equal(4, im.Bands);
            }

            FileLoader("pdfload", Helper.PdfFile, PdfValid);
            BufferLoader("pdfload_buffer", Helper.PdfFile, PdfValid);

            var x = Image.NewFromFile(Helper.PdfFile);
            var y = Image.NewFromFile(Helper.PdfFile, kwargs: new VOption
            {
                { "scale", 2 }
            });

            Assert.True(Math.Abs(x.Width * 2 - y.Width) < 2);
            Assert.True(Math.Abs(x.Height * 2 - y.Height) < 2);

            x = Image.NewFromFile(Helper.PdfFile);
            y = Image.NewFromFile(Helper.PdfFile, kwargs: new VOption
            {
                { "dpi", 144 }
            });
            Assert.True(Math.Abs(x.Width * 2 - y.Width) < 2);
            Assert.True(Math.Abs(x.Height * 2 - y.Height) < 2);
        }
        public void TestHoughLine()
        {
            // hough_line changed the way it codes parameter space in 8.7 ... don't
            // test earlier versions
            Skip.IfNot(NetVips.AtLeastLibvips(8, 7), "requires libvips >= 8.7");

            var test = Image.Black(100, 100).DrawLine(new double[] { 100 }, 10, 90, 90, 10);

            foreach (var fmt in Helper.AllFormats)
            {
                var im    = test.Cast(fmt);
                var hough = im.HoughLine();

                var maxPos = hough.MaxPos();
                var x      = maxPos[1];
                var y      = maxPos[2];

                var angle    = Math.Floor(180.0 * x / hough.Width);
                var distance = Math.Floor(test.Height * y / hough.Height);

                Assert.Equal(45, angle);
                Assert.Equal(70, distance);
            }
        }
Exemple #20
0
        public void TestMapim()
        {
            var im = Image.NewFromFile(Helper.JpegFile);

            var p = ToPolar(im);
            var r = ToRectangular(p);

            // the left edge (which is squashed to the origin) will be badly
            // distorted, but the rest should not be too bad
            var a = r.Crop(50, 0, im.Width - 50, im.Height).Gaussblur(2);
            var b = im.Crop(50, 0, im.Width - 50, im.Height).Gaussblur(2);

            Assert.True((a - b).Abs().Max() < 20);

            // this was a bug at one point, strangely, if executed with debug
            // enabled
            // fixed in 8.7.3
            if (NetVips.AtLeastLibvips(8, 7, 3))
            {
                var mp     = Image.Xyz(im.Width, im.Height);
                var interp = Interpolate.NewFromName("bicubic");
                Assert.Equal(im.Avg(), im.Mapim(mp, interp).Avg());
            }
        }
        public void TestNotEq()
        {
            dynamic NotEq(dynamic x, dynamic y)
            {
                if (y is Image rightImage && !(x is Image))
                {
                    return(x != rightImage);
                }

                if (x is Image leftImage && !(y is Image))
                {
                    return(y != leftImage);
                }

                if (y is Image)
                {
                    return(y.NotEqual(x));
                }

                return(x != y ? 255 : 0);
            }

            RunArithConst(NotEq);
            RunArith(NotEq);

            if (NetVips.AtLeastLibvips(8, 9))
            {
                // comparisons against out of range values should always fail, and
                // comparisons to fractional values should always fail
                var z = Image.Grey(256, 256, uchar: true);

                Assert.Equal(0, z.Equal(1000).Max());
                Assert.Equal(255, z.Equal(12).Max());
                Assert.Equal(0, z.Equal(12.5).Max());
            }
        }
Exemple #22
0
        public void TestWebp()
        {
            Skip.IfNot(Helper.Have("webpload") && File.Exists(Helper.WebpFile), "no webp support, skipping test");

            void WebpValid(Image im)
            {
                var a = im[10, 10];

                // different webp versions use different rounding systems leading
                // to small variations
                Helper.AssertAlmostEqualObjects(new double[] { 71, 166, 236 }, a, 2);
                Assert.Equal(550, im.Width);
                Assert.Equal(368, im.Height);
                Assert.Equal(3, im.Bands);
            }

            FileLoader("webpload", Helper.WebpFile, WebpValid);
            BufferLoader("webpload_buffer", Helper.WebpFile, WebpValid);
            SaveLoadBuffer("webpsave_buffer", "webpload_buffer", _colour, 60);
            SaveLoad("%s.webp", _colour);
            if (Helper.Have("webpload_source"))
            {
                SaveLoadStream(".webp", "", _colour, 80);
            }

            // test lossless mode
            var x   = Image.NewFromFile(Helper.WebpFile);
            var buf = x.WebpsaveBuffer(lossless: true);
            var im2 = Image.NewFromBuffer(buf);

            Assert.True(Math.Abs(x.Avg() - im2.Avg()) < 1);

            // higher Q should mean a bigger buffer
            var b1 = x.WebpsaveBuffer(q: 10);
            var b2 = x.WebpsaveBuffer(q: 90);

            Assert.True(b2.Length > b1.Length);

            // try saving an image with an ICC profile and reading it back ... if we
            // can do it, our webp supports metadata load/save
            buf = _colour.WebpsaveBuffer();
            x   = Image.NewFromBuffer(buf);
            if (x.Contains("icc-profile-data"))
            {
                // verify that the profile comes back unharmed
                var p1 = _colour.Get("icc-profile-data");
                var p2 = x.Get("icc-profile-data");
                Assert.Equal(p1, p2);

                // add tests for exif, xmp, ipct
                // the exif test will need us to be able to walk the header,
                // we can't just check exif-data

                // we can test that exif changes change the output of webpsave
                // first make sure we have exif support
                var z = Image.NewFromFile(Helper.JpegFile);
                if (z.Contains("exif-ifd0-Orientation"))
                {
                    x = _colour.Copy();
                    x.Set("orientation", 6);
                    buf = x.WebpsaveBuffer();
                    var y = Image.NewFromBuffer(buf);
                    Assert.Equal(6, y.Get("orientation"));
                }
            }

            // try converting an animated gif to webp ... can't do back to gif
            // again without IM support
            // added in 8.8
            if (Helper.Have("gifload") && NetVips.AtLeastLibvips(8, 8))
            {
                var x1 = Image.NewFromFile(Helper.GifAnimFile, kwargs: new VOption
                {
                    { "n", -1 }
                });
                var w1 = x1.WebpsaveBuffer(q: 10);
                var x2 = Image.NewFromBuffer(w1, kwargs: new VOption
                {
                    { "n", -1 }
                });
                Assert.Equal(x2.Width, x1.Width);
                Assert.Equal(x2.Height, x1.Height);

                var delayName = NetVips.AtLeastLibvips(8, 9) ? "delay" : "gif-delay";
                Assert.Equal(x2.Get(delayName), x1.Get(delayName));
                Assert.Equal(x2.Get("page-height"), x1.Get("page-height"));
                Assert.Equal(x2.Get("gif-loop"), x1.Get("gif-loop"));
            }
        }
Exemple #23
0
        public void TestColourspace()
        {
            // mid-grey in Lab ... put 42 in the extra band, it should be copied
            // unmodified
            var test = Image.Black(100, 100) + new[] { 50, 0, 0, 42 };

            test = test.Copy(interpretation: Enums.Interpretation.Lab);

            // a long series should come in a circle
            var im = test;

            foreach (var col in Helper.ColourColourspaces.Concat(new[] { Enums.Interpretation.Lab }))
            {
                im = im.Colourspace(col);
                Assert.Equal(col, im.Interpretation);

                for (var i = 0; i < 4; i++)
                {
                    var minL = im[i].Min();
                    var maxH = im[i].Max();
                    Assert.Equal(minL, maxH);
                }

                var pixel = im[10, 10];
                Assert.Equal(42, pixel[3], 2);
            }

            // alpha won't be equal for RGB16, but it should be preserved if we go
            // there and back
            im = im.Colourspace(Enums.Interpretation.Rgb16);
            im = im.Colourspace(Enums.Interpretation.Lab);

            var before = test[10, 10];
            var after  = im[10, 10];

            Helper.AssertAlmostEqualObjects(before, after, 0.1);

            // go between every pair of colour spaces
            foreach (var start in Helper.ColourColourspaces)
            {
                foreach (var end in Helper.ColourColourspaces)
                {
                    im = test.Colourspace(start);
                    var im2 = im.Colourspace(end);
                    var im3 = im2.Colourspace(Enums.Interpretation.Lab);
                    before = test[10, 10];
                    after  = im3[10, 10];
                    Helper.AssertAlmostEqualObjects(before, after, 0.1);
                }
            }

            // test Lab->XYZ on mid-grey
            // checked against http://www.brucelindbloom.com
            im    = test.Colourspace(Enums.Interpretation.Xyz);
            after = im[10, 10];
            Helper.AssertAlmostEqualObjects(new[]
            {
                17.5064,
                18.4187,
                20.0547,
                42
            }, after);

            // grey->colour->grey should be equal
            foreach (var monoFmt in Helper.MonoColourspaces)
            {
                var testGrey = test.Colourspace(monoFmt);
                im = testGrey;
                foreach (var col in Helper.ColourColourspaces.Concat(new[] { monoFmt }))
                {
                    im = im.Colourspace(col);
                    Assert.Equal(col, im.Interpretation);
                }

                var pixelBefore = testGrey[10, 10];
                var alphaBefore = pixelBefore[1];
                var pixelAfter  = im[10, 10];
                var alphaAfter  = pixelAfter[1];
                Assert.True(Math.Abs(alphaAfter - alphaBefore) < 1);

                // GREY16 can wind up rather different due to rounding but 8-bit we should hit exactly
                Assert.True(
                    Math.Abs(pixelAfter[0] - pixelBefore[0]) < (monoFmt == Enums.Interpretation.Grey16 ? 30 : 1));
            }

            if (NetVips.AtLeastLibvips(8, 8))
            {
                // we should be able to go from cmyk to any 3-band space and back again,
                // approximately
                var cmyk = test.Colourspace(Enums.Interpretation.Cmyk);
                foreach (var end in Helper.ColourColourspaces)
                {
                    im = cmyk.Colourspace(end);
                    var im2 = im.Colourspace(Enums.Interpretation.Cmyk);

                    before = cmyk[10, 10];
                    after  = im2[10, 10];

                    Helper.AssertAlmostEqualObjects(before, after, 10);
                }
            }
        }
Exemple #24
0
        public void TestThumbnail()
        {
            Skip.IfNot(NetVips.AtLeastLibvips(8, 5), "requires libvips >= 8.5");

            var im = Image.Thumbnail(Helper.JpegFile, 100);

            Assert.Equal(100, im.Width);
            Assert.Equal(3, im.Bands);

            // the average shouldn't move too much
            var imOrig = Image.NewFromFile(Helper.JpegFile);

            Assert.True(Math.Abs(imOrig.Avg() - im.Avg()) < 1);

            // make sure we always get the right width
            for (var width = 1000; width >= 1; width -= 13)
            {
                im = Image.Thumbnail(Helper.JpegFile, width);
                Assert.Equal(width, im.Width);
            }

            // should fit one of width or height
            im = Image.Thumbnail(Helper.JpegFile, 100, height: 300);
            Assert.Equal(100, im.Width);
            Assert.NotEqual(300, im.Height);
            im = Image.Thumbnail(Helper.JpegFile, 300, height: 100);
            Assert.NotEqual(300, im.Width);
            Assert.Equal(100, im.Height);

            // with @crop, should fit both width and height
            im = Image.Thumbnail(Helper.JpegFile, 100, height: 300, crop: "centre");
            Assert.Equal(100, im.Width);
            Assert.Equal(300, im.Height);

            var im1 = Image.Thumbnail(Helper.JpegFile, 100);
            var buf = File.ReadAllBytes(Helper.JpegFile);
            var im2 = Image.ThumbnailBuffer(buf, 100);

            Assert.True(Math.Abs(im1.Avg() - im2.Avg()) < 1);

            // OME-TIFF subifd thumbnail support added in 8.10
            if (NetVips.AtLeastLibvips(8, 10))
            {
                // should be able to thumbnail many-page tiff
                im = Image.Thumbnail(Helper.OmeFile, 100);
                Assert.Equal(100, im.Width);
                Assert.Equal(38, im.Height);

                // should be able to thumbnail individual pages from many-page tiff
                // should be able to thumbnail individual pages from many-page tiff
                im = Image.Thumbnail(Helper.OmeFile + "[page=0]", 100);
                Assert.Equal(100, im.Width);
                Assert.Equal(38, im.Height);
                im2 = Image.Thumbnail(Helper.OmeFile + "[page=1]", 100);
                Assert.Equal(100, im2.Width);
                Assert.Equal(38, im2.Height);
                Assert.True((im1 - im2).Abs().Max() != 0);

                // should be able to thumbnail entire many-page tiff as a toilet-roll
                // image
                im = Image.Thumbnail(Helper.OmeFile + "[n=-1]", 100);
                Assert.Equal(100, im.Width);
                Assert.Equal(570, im.Height);

                if (Helper.Have("heifload"))
                {
                    // this image is orientation 6 ... thumbnail should flip it
                    var thumb = Image.Thumbnail(Helper.HeicFile, 100);

                    // thumb should be portrait
                    Assert.True(thumb.Width < thumb.Height);
                    Assert.Equal(100, thumb.Height);
                }
            }
        }
Exemple #25
0
        public void TestGifLoad()
        {
            Skip.IfNot(Helper.Have("gifload") && File.Exists(Helper.GifFile), "no gif support, skipping test");

            void GifValid(Image im)
            {
                var a = im[10, 10];

                Assert.Equal(new double[] { 33 }, a);
                Assert.Equal(159, im.Width);
                Assert.Equal(203, im.Height);
                Assert.Equal(1, im.Bands);
            }

            FileLoader("gifload", Helper.GifFile, GifValid);
            BufferLoader("gifload_buffer", Helper.GifFile, GifValid);

            // test fallback stream mechanism, needs libvips >= 8.9
            if (NetVips.AtLeastLibvips(8, 9))
            {
                // file-based loader fallback
                using (var input = Source.NewFromFile(Helper.GifFile))
                {
                    var img = Image.NewFromSource(input, access: Enums.Access.Sequential);
                    GifValid(img);
                }

                // buffer-based loader fallback
                using (var input = File.OpenRead(Helper.GifFile))
                {
                    var img = Image.NewFromStream(input, access: Enums.Access.Sequential);
                    GifValid(img);
                }
            }

            // 'n' param added in 8.5
            if (NetVips.AtLeastLibvips(8, 5))
            {
                var x1 = Image.NewFromFile(Helper.GifAnimFile);
                var x2 = Image.NewFromFile(Helper.GifAnimFile, kwargs: new VOption
                {
                    { "n", 2 }
                });
                Assert.Equal(2 * x1.Height, x2.Height);
                var pageHeight = x2.Get("page-height");
                Assert.Equal(x1.Height, pageHeight);

                x2 = Image.NewFromFile(Helper.GifAnimFile, kwargs: new VOption
                {
                    { "n", -1 }
                });
                Assert.Equal(5 * x1.Height, x2.Height);

                // delay metadata was added in libvips 8.9
                if (NetVips.AtLeastLibvips(8, 9))
                {
                    // our test gif has delay 0 for the first frame set in error
                    Assert.Equal(new[] { 0, 50, 50, 50, 50 }, x2.Get("delay"));
                }

                x2 = Image.NewFromFile(Helper.GifAnimFile, kwargs: new VOption
                {
                    { "page", 1 },
                    { "n", -1 }
                });
                Assert.Equal(4 * x1.Height, x2.Height);
            }
        }
Exemple #26
0
        public void TestDzSave()
        {
            Skip.IfNot(Helper.Have("dzsave"), "no dzsave support, skipping test");

            // dzsave is hard to test, there are so many options
            // test each option separately and hope they all function together
            // correctly

            // default deepzoom layout ... we must use png here, since we want to
            // test the overlap for equality
            var filename = Helper.GetTemporaryFile(_tempDir);

            _colour.Dzsave(filename, suffix: ".png");

            // test horizontal overlap ... expect 256 step, overlap 1
            var x = Image.NewFromFile(filename + "_files/10/0_0.png");

            Assert.Equal(255, x.Width);
            var y = Image.NewFromFile(filename + "_files/10/1_0.png");

            Assert.Equal(256, y.Width);

            // the right two columns of x should equal the left two columns of y
            var left  = x.ExtractArea(x.Width - 2, 0, 2, x.Height);
            var right = y.ExtractArea(0, 0, 2, y.Height);

            Assert.Equal(0, (left - right).Abs().Max());

            // test vertical overlap
            Assert.Equal(255, x.Height);
            y = Image.NewFromFile(filename + "_files/10/0_1.png");
            Assert.Equal(256, y.Height);

            // the bottom two rows of x should equal the top two rows of y
            var top    = x.ExtractArea(0, x.Height - 2, x.Width, 2);
            var bottom = y.ExtractArea(0, 0, y.Width, 2);

            Assert.Equal(0, (top - bottom).Abs().Max());

            // there should be a bottom layer
            x = Image.NewFromFile(filename + "_files/0/0_0.png");
            Assert.Equal(1, x.Width);
            Assert.Equal(1, x.Height);

            // 10 should be the final layer
            Assert.False(Directory.Exists(filename + "_files/11"));

            // default google layout
            filename = Helper.GetTemporaryFile(_tempDir);
            _colour.Dzsave(filename, layout: "google");

            // test bottom-right tile ... default is 256x256 tiles, overlap 0
            x = Image.NewFromFile(filename + "/2/2/3.jpg");
            Assert.Equal(256, x.Width);
            Assert.Equal(256, x.Height);
            Assert.False(Directory.Exists(filename + "/2/2/4.jpg"));
            Assert.False(Directory.Exists(filename + "/3"));
            x = Image.NewFromFile(filename + "/blank.png");
            Assert.Equal(256, x.Width);
            Assert.Equal(256, x.Height);

            // google layout with overlap ... verify that we clip correctly

            // overlap 1, 510x510 pixels, 256 pixel tiles, should be exactly 2x2
            // tiles, though in fact the bottom and right edges will be white
            filename = Helper.GetTemporaryFile(_tempDir);

            _colour.ExtractArea(0, 0, 510, 510).Dzsave(filename, layout: "google", overlap: 1, depth: "one");

            x = Image.NewFromFile(filename + "/0/1/1.jpg");
            Assert.Equal(256, x.Width);
            Assert.Equal(256, x.Height);
            Assert.False(Directory.Exists(filename + "/0/2/2.jpg"));

            // with 511x511, it'll fit exactly into 2x2 -- we we actually generate
            // 3x3, since we output the overlaps
            // 8.6 revised the rules on overlaps, so don't test earlier than that
            if (NetVips.AtLeastLibvips(8, 6))
            {
                filename = Helper.GetTemporaryFile(_tempDir);
                _colour.ExtractArea(0, 0, 511, 511).Dzsave(filename, layout: "google", overlap: 1, depth: "one");

                x = Image.NewFromFile(filename + "/0/2/2.jpg");
                Assert.Equal(256, x.Width);
                Assert.Equal(256, x.Height);
                Assert.False(Directory.Exists(filename + "/0/3/3.jpg"));
            }

            // default zoomify layout
            filename = Helper.GetTemporaryFile(_tempDir);
            _colour.Dzsave(filename, layout: "zoomify");

            // 256x256 tiles, no overlap
            Assert.True(File.Exists(filename + "/ImageProperties.xml"));
            x = Image.NewFromFile(filename + "/TileGroup0/2-3-2.jpg");
            Assert.Equal(256, x.Width);
            Assert.Equal(256, x.Height);

            // test zip output
            filename = Helper.GetTemporaryFile(_tempDir, ".zip");
            _colour.Dzsave(filename);

            Assert.True(File.Exists(filename));
            Assert.False(Directory.Exists(filename + "_files"));
            Assert.False(File.Exists(filename + ".dzi"));

            // test compressed zip output
            var filename2 = Helper.GetTemporaryFile(_tempDir, ".zip");

            _colour.Dzsave(filename2, compression: -1);

            Assert.True(File.Exists(filename2));
            Assert.True(new FileInfo(filename2).Length < new FileInfo(filename).Length);

            // test suffix
            filename = Helper.GetTemporaryFile(_tempDir);
            _colour.Dzsave(filename, suffix: ".png");

            x = Image.NewFromFile(filename + "_files/10/0_0.png");
            Assert.Equal(255, x.Width);

            // test overlap
            filename = Helper.GetTemporaryFile(_tempDir);
            _colour.Dzsave(filename, overlap: 200);

            x = Image.NewFromFile(filename + "_files/10/1_1.jpeg");
            Assert.Equal(654, x.Width);

            // test tile-size
            filename = Helper.GetTemporaryFile(_tempDir);
            _colour.Dzsave(filename, tileSize: 512);

            y = Image.NewFromFile(filename + "_files/10/0_0.jpeg");
            Assert.Equal(513, y.Width);
            Assert.Equal(513, y.Height);

            // test save to memory buffer
            if (Helper.Have("dzsave_buffer"))
            {
                filename = Helper.GetTemporaryFile(_tempDir, ".zip");
                var baseName = Path.GetFileNameWithoutExtension(filename);

                _colour.Dzsave(filename);

                var buf1 = File.ReadAllBytes(filename);
                var buf2 = _colour.DzsaveBuffer(basename: baseName);
                Assert.Equal(buf1.Length, buf2.Length);

                // we can't test the bytes are exactly equal -- the timestamps will
                // be different

                // added in 8.7
                if (NetVips.AtLeastLibvips(8, 7))
                {
                    _ = _colour.DzsaveBuffer(regionShrink: "mean");
                    _ = _colour.DzsaveBuffer(regionShrink: "mode");
                    _ = _colour.DzsaveBuffer(regionShrink: "median");
                }
            }
        }
Exemple #27
0
        public void TestJpeg()
        {
            Skip.IfNot(Helper.Have("jpegload"), "no jpeg support in this vips, skipping test");

            void JpegValid(Image im)
            {
                var a = im[10, 10];

                Assert.Equal(new double[] { 6, 5, 3 }, a);
                var profile = (byte[])im.Get("icc-profile-data");

                Assert.Equal(1352, profile.Length);
                Assert.Equal(1024, im.Width);
                Assert.Equal(768, im.Height);
                Assert.Equal(3, im.Bands);
            }

            FileLoader("jpegload", Helper.JpegFile, JpegValid);
            SaveLoad("%s.jpg", _mono);
            SaveLoad("%s.jpg", _colour);

            BufferLoader("jpegload_buffer", Helper.JpegFile, JpegValid);
            SaveLoadBuffer("jpegsave_buffer", "jpegload_buffer", _colour, 80);
            if (Helper.Have("jpegload_source"))
            {
                SaveLoadStream(".jpg", "", _colour, 80);
            }

            // see if we have exif parsing: our test image has this field
            var x = Image.NewFromFile(Helper.JpegFile);

            if (x.Contains("exif-ifd0-Orientation"))
            {
                // we need a copy of the image to set the new metadata on
                // otherwise we get caching problems

                // can set, save and load new orientation
                x = Image.NewFromFile(Helper.JpegFile);
                x = x.Copy();

                x.Set("orientation", 2);

                var filename = Helper.GetTemporaryFile(_tempDir, ".jpg");
                x.WriteToFile(filename);

                x = Image.NewFromFile(filename);
                var y = x.Get("orientation");
                Assert.Equal(2, y);

                // can remove orientation, save, load again, orientation
                // has reset
                x = x.Copy();
                x.Remove("orientation");

                filename = Helper.GetTemporaryFile(_tempDir, ".jpg");
                x.WriteToFile(filename);

                x = Image.NewFromFile(filename);
                y = x.Get("orientation");
                Assert.Equal(1, y);

                // autorotate load works
                x = Image.NewFromFile(Helper.JpegFile);
                x = x.Copy();
                x.Set("orientation", 6);

                filename = Helper.GetTemporaryFile(_tempDir, ".jpg");
                x.WriteToFile(filename);
                var x1 = Image.NewFromFile(filename);
                var x2 = Image.NewFromFile(filename, kwargs: new VOption
                {
                    { "autorotate", true }
                });
                Assert.Equal(x1.Width, x2.Height);
                Assert.Equal(x1.Height, x2.Width);

                // can set, save and reload ASCII string fields
                // added in 8.7
                if (NetVips.AtLeastLibvips(8, 7))
                {
                    x = Image.NewFromFile(Helper.JpegFile);
                    x = x.Copy();

                    x.Set(GValue.GStrType, "exif-ifd0-ImageDescription", "hello world");

                    filename = Helper.GetTemporaryFile(_tempDir, ".jpg");
                    x.WriteToFile(filename);

                    x = Image.NewFromFile(filename);
                    y = x.Get("exif-ifd0-ImageDescription");

                    // can't use Assert.Equal since the string will have an extra " (xx, yy, zz)"
                    // format area at the end
                    Assert.StartsWith("hello world", (string)y);

                    // can set, save and reload UTF16 string fields ... NetVips is
                    // utf8, but it will be coded as utf16 and back for the XP* fields
                    x = Image.NewFromFile(Helper.JpegFile);
                    x = x.Copy();

                    x.Set(GValue.GStrType, "exif-ifd0-XPComment", "йцук");

                    filename = Helper.GetTemporaryFile(_tempDir, ".jpg");
                    x.WriteToFile(filename);

                    x = Image.NewFromFile(filename);
                    y = x.Get("exif-ifd0-XPComment");

                    // can't use Assert.Equal since the string will have an extra " (xx, yy, zz)"
                    // format area at the end
                    Assert.StartsWith("йцук", (string)y);

                    // can set/save/load UserComment, a tag which has the
                    // encoding in the first 8 bytes ... though libexif only supports
                    // ASCII for this
                    x = Image.NewFromFile(Helper.JpegFile);
                    x = x.Copy();

                    x.Set(GValue.GStrType, "exif-ifd2-UserComment", "hello world");

                    filename = Helper.GetTemporaryFile(_tempDir, ".jpg");
                    x.WriteToFile(filename);

                    x = Image.NewFromFile(filename);
                    y = x.Get("exif-ifd2-UserComment");

                    // can't use Assert.Equal since the string will have an extra " (xx, yy, zz)"
                    // format area at the end
                    Assert.StartsWith("hello world", (string)y);
                }
            }
        }
Exemple #28
0
        public void TestTiff()
        {
            Skip.IfNot(Helper.Have("tiffload") && File.Exists(Helper.TifFile), "no tiff support, skipping test");

            void TiffValid(Image im)
            {
                var a = im[10, 10];

                Assert.Equal(new[] { 38671.0, 33914.0, 26762.0 }, a);
                Assert.Equal(290, im.Width);
                Assert.Equal(442, im.Height);
                Assert.Equal(3, im.Bands);
            }

            FileLoader("tiffload", Helper.TifFile, TiffValid);
            BufferLoader("tiffload_buffer", Helper.TifFile, TiffValid);
            if (NetVips.AtLeastLibvips(8, 5))
            {
                SaveLoadBuffer("tiffsave_buffer", "tiffload_buffer", _colour);
            }

            SaveLoad("%s.tif", _mono);
            SaveLoad("%s.tif", _colour);
            SaveLoad("%s.tif", _cmyk);

            SaveLoad("%s.tif", _oneBit);
            SaveLoadFile(".tif", "[squash]", _oneBit);
            SaveLoadFile(".tif", "[miniswhite]", _oneBit);
            SaveLoadFile(".tif", "[squash,miniswhite]", _oneBit);

            SaveLoadFile(".tif", $"[profile={Helper.SrgbFile}]", _colour);
            SaveLoadFile(".tif", "[tile]", _colour);
            SaveLoadFile(".tif", "[tile,pyramid]", _colour);
            SaveLoadFile(".tif", "[tile,pyramid,compression=jpeg]", _colour, 80);
            SaveLoadFile(".tif", "[bigtiff]", _colour);
            SaveLoadFile(".tif", "[compression=jpeg]", _colour, 80);
            SaveLoadFile(".tif", "[tile,tile-width=256]", _colour, 10);

            var filename = Helper.GetTemporaryFile(_tempDir, ".tif");
            var x        = Image.NewFromFile(Helper.TifFile);

            x = x.Copy();
            x.Set("orientation", 2);
            x.WriteToFile(filename);
            x = Image.NewFromFile(filename);
            var y = x.Get("orientation");

            Assert.Equal(2, y);

            filename = Helper.GetTemporaryFile(_tempDir, ".tif");
            x        = Image.NewFromFile(Helper.TifFile);
            x        = x.Copy();
            x.Set("orientation", 2);
            x.WriteToFile(filename);
            x = Image.NewFromFile(filename);
            y = x.Get("orientation");
            Assert.Equal(2, y);
            x = x.Copy();
            x.Remove("orientation");

            filename = Helper.GetTemporaryFile(_tempDir, ".tif");
            x.WriteToFile(filename);
            x = Image.NewFromFile(filename);
            y = x.Get("orientation");
            Assert.Equal(1, y);

            filename = Helper.GetTemporaryFile(_tempDir, ".tif");
            x        = Image.NewFromFile(Helper.TifFile);
            x        = x.Copy();
            x.Set("orientation", 6);
            x.WriteToFile(filename);
            var x1 = Image.NewFromFile(filename);
            var x2 = Image.NewFromFile(filename, kwargs: new VOption
            {
                { "autorotate", true }
            });

            Assert.Equal(x1.Width, x2.Height);
            Assert.Equal(x1.Height, x2.Width);

            // OME support in 8.5
            if (NetVips.AtLeastLibvips(8, 5))
            {
                x = Image.NewFromFile(Helper.OmeFile);
                Assert.Equal(439, x.Width);
                Assert.Equal(167, x.Height);
                var pageHeight = x.Height;

                x = Image.NewFromFile(Helper.OmeFile, kwargs: new VOption
                {
                    { "n", -1 }
                });
                Assert.Equal(439, x.Width);
                Assert.Equal(pageHeight * 15, x.Height);

                x = Image.NewFromFile(Helper.OmeFile, kwargs: new VOption
                {
                    { "page", 1 },
                    { "n", -1 }
                });
                Assert.Equal(439, x.Width);
                Assert.Equal(pageHeight * 14, x.Height);

                x = Image.NewFromFile(Helper.OmeFile, kwargs: new VOption
                {
                    { "page", 1 },
                    { "n", 2 }
                });
                Assert.Equal(439, x.Width);
                Assert.Equal(pageHeight * 2, x.Height);

                x = Image.NewFromFile(Helper.OmeFile, kwargs: new VOption
                {
                    { "n", -1 }
                });
                Assert.Equal(96, x[0, 166][0]);
                Assert.Equal(0, x[0, 167][0]);
                Assert.Equal(1, x[0, 168][0]);

                filename = Helper.GetTemporaryFile(_tempDir, ".tif");
                x.WriteToFile(filename);

                x = Image.NewFromFile(filename, kwargs: new VOption
                {
                    { "n", -1 }
                });
                Assert.Equal(439, x.Width);
                Assert.Equal(pageHeight * 15, x.Height);
                Assert.Equal(96, x[0, 166][0]);
                Assert.Equal(0, x[0, 167][0]);
                Assert.Equal(1, x[0, 168][0]);
            }

            // pyr save to buffer added in 8.6
            if (NetVips.AtLeastLibvips(8, 6))
            {
                x = Image.NewFromFile(Helper.TifFile);
                var buf = x.TiffsaveBuffer(tile: true, pyramid: true);
                filename = Helper.GetTemporaryFile(_tempDir, ".tif");
                x.Tiffsave(filename, tile: true, pyramid: true);
                var buf2 = File.ReadAllBytes(filename);
                Assert.Equal(buf.Length, buf2.Length);

                var a = Image.NewFromBuffer(buf, kwargs: new VOption
                {
                    { "page", 2 }
                });
                var b = Image.NewFromBuffer(buf2, kwargs: new VOption
                {
                    { "page", 2 }
                });
                Assert.Equal(a.Width, b.Width);
                Assert.Equal(a.Height, b.Height);
                Assert.Equal(a.Avg(), b.Avg());
            }

            // region-shrink added in 8.7
            if (NetVips.AtLeastLibvips(8, 7))
            {
                x = Image.NewFromFile(Helper.TifFile);
                _ = x.TiffsaveBuffer(tile: true, pyramid: true, regionShrink: "mean");
                _ = x.TiffsaveBuffer(tile: true, pyramid: true, regionShrink: "mode");
                _ = x.TiffsaveBuffer(tile: true, pyramid: true, regionShrink: "median");
            }
        }
Exemple #29
0
        public void TestMagickLoad()
        {
            Skip.IfNot(Helper.Have("magickload") &&
                       File.Exists(Helper.BmpFile), "no magick support, skipping test");

            void BmpValid(Image im)
            {
                var a = im[100, 100];

                Helper.AssertAlmostEqualObjects(new double[] { 227, 216, 201 }, a);
                Assert.Equal(1419, im.Width);
                Assert.Equal(1001, im.Height);
            }

            FileLoader("magickload", Helper.BmpFile, BmpValid);
            BufferLoader("magickload_buffer", Helper.BmpFile, BmpValid);

            // we should have rgb or rgba for svg files ... different versions of
            // IM handle this differently. GM even gives 1 band.
            var x = Image.Magickload(Helper.SvgFile);

            Assert.True(x.Bands == 3 || x.Bands == 4 || x.Bands == 1);

            // density should change size of generated svg
            x = Image.Magickload(Helper.SvgFile, density: "100");
            var width  = x.Width;
            var height = x.Height;

            // This seems to fail on travis, no idea why, some problem in their IM
            // perhaps
            //x = Image.Magickload(Helper.SvgFile, density: "200");
            //Assert.Equal(width * 2, x.Width);
            //Assert.Equal(height * 2, x.Height);

            // page/n let you pick a range of pages
            // 'n' param added in 8.5
            if (NetVips.AtLeastLibvips(8, 5))
            {
                x      = Image.Magickload(Helper.GifAnimFile);
                width  = x.Width;
                height = x.Height;
                x      = Image.Magickload(Helper.GifAnimFile, page: 1, n: 2);
                Assert.Equal(width, x.Width);
                Assert.Equal(height * 2, x.Height);

                var pageHeight = x.Get("page-height");
                Assert.Equal(height, pageHeight);
            }

            // should work for dicom
            x = Image.Magickload(Helper.DicomFile);
            Assert.Equal(128, x.Width);
            Assert.Equal(128, x.Height);

            // some IMs are 3 bands, some are 1, can't really test
            // Assert.Equal(1, x.Bands);

            // libvips has its own sniffer for ICO, test that
            // added in 8.7
            if (NetVips.AtLeastLibvips(8, 7))
            {
                var buf = File.ReadAllBytes(Helper.IcoFile);
                var im  = Image.NewFromBuffer(buf);
                Assert.Equal(16, im.Width);
                Assert.Equal(16, im.Height);
            }
        }