Beispiel #1
0
        public void ShouldUsePamAsTheIntermediateFormatWhenSpecificied()
        {
            var videoDefines = new VideoReadDefines(MagickFormat.Mp4)
            {
                IntermediateFormat = IntermediateFormat.Pam,
            };

            var readSettings = new MagickReadSettings();

            readSettings.SetDefines(videoDefines);

            using (var images = new MagickImageCollection(Files.Coders.TestMP4, readSettings))
            {
                Assert.Equal(8, images.Count);
            }
        }
Beispiel #2
0
        public Image <TPixel> Decode <TPixel>(Configuration configuration, Stream stream)
            where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel <TPixel>
        {
            var bmpReadDefines = new BmpReadDefines
            {
                IgnoreFileSize = !this.validate
            };

            var settings = new MagickReadSettings();

            settings.SetDefines(bmpReadDefines);

            using var magickImageCollection = new MagickImageCollection(stream, settings);
            var framesList = new List <ImageFrame <TPixel> >();

            foreach (IMagickImage <ushort> magicFrame in magickImageCollection)
            {
                var frame = new ImageFrame <TPixel>(configuration, magicFrame.Width, magicFrame.Height);
                framesList.Add(frame);

                MemoryGroup <TPixel> framePixels = frame.PixelBuffer.FastMemoryGroup;

                using IUnsafePixelCollection <ushort> pixels = magicFrame.GetPixelsUnsafe();
                if (magicFrame.Depth == 8 || magicFrame.Depth == 1)
                {
                    byte[] data = pixels.ToByteArray(PixelMapping.RGBA);

                    FromRgba32Bytes(configuration, data, framePixels);
                }
                else if (magicFrame.Depth == 16)
                {
                    ushort[]    data  = pixels.ToShortArray(PixelMapping.RGBA);
                    Span <byte> bytes = MemoryMarshal.Cast <ushort, byte>(data.AsSpan());
                    FromRgba64Bytes(configuration, bytes, framePixels);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            return(new Image <TPixel>(configuration, new ImageMetadata(), framesList));
        }
Beispiel #3
0
        public Image <TPixel> Decode <TPixel>(Configuration configuration, Stream stream)
            where TPixel : unmanaged, ImageSharp.PixelFormats.IPixel <TPixel>
        {
            var bmpReadDefines = new BmpReadDefines
            {
                IgnoreFileSize = !this.validate
            };

            var settings = new MagickReadSettings();

            settings.SetDefines(bmpReadDefines);

            using var magickImage = new MagickImage(stream, settings);
            var result = new Image <TPixel>(configuration, magickImage.Width, magickImage.Height);
            MemoryGroup <TPixel> resultPixels = result.GetRootFramePixelBuffer().FastMemoryGroup;

            using (IUnsafePixelCollection <ushort> pixels = magickImage.GetPixelsUnsafe())
            {
                if (magickImage.Depth == 8)
                {
                    byte[] data = pixels.ToByteArray(PixelMapping.RGBA);

                    FromRgba32Bytes(configuration, data, resultPixels);
                }
                else if (magickImage.Depth == 16)
                {
                    ushort[]    data  = pixels.ToShortArray(PixelMapping.RGBA);
                    Span <byte> bytes = MemoryMarshal.Cast <ushort, byte>(data.AsSpan());
                    FromRgba64Bytes(configuration, bytes, resultPixels);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }

            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Load image from file
        /// </summary>
        /// <param name="filename">Full path of image file</param>
        /// <param name="size">A custom size of image</param>
        /// <param name="colorProfileName">Name or Full path of color profile</param>
        /// <param name="isApplyColorProfileForAll">If FALSE, only the images with embedded profile will be applied</param>
        /// <param name="quality">Image quality</param>
        /// <param name="channel">MagickImage.Channel value</param>
        /// <param name="useEmbeddedThumbnail">Return the embedded thumbnail if required size was not found.</param>
        /// <param name="useRawThumbnail">Return the RAW embedded thumbnail if found.</param>
        /// <param name="forceLoadFirstPage">Only load first page of the image</param>
        /// <returns>Bitmap</returns>
        public static ImgData Load(
            string filename,
            Size size = new Size(),
            string colorProfileName        = "sRGB",
            bool isApplyColorProfileForAll = false,
            int quality = 100,
            int channel = -1,
            bool useEmbeddedThumbnail = false,
            bool useRawThumbnail      = true,
            bool forceLoadFirstPage   = false
            )
        {
            Bitmap        bitmap       = null;
            IExifProfile  exif         = null;
            IColorProfile colorProfile = null;

            var ext      = Path.GetExtension(filename).ToUpperInvariant();
            var settings = new MagickReadSettings();

            #region Settings
            if (ext == ".SVG")
            {
                settings.BackgroundColor = MagickColors.Transparent;
                settings.SetDefine("svg:xml-parse-huge", "true");
            }

            if (size.Width > 0 && size.Height > 0)
            {
                settings.Width  = size.Width;
                settings.Height = size.Height;
            }


            // Fixed #708: length and filesize do not match
            settings.SetDefines(new BmpReadDefines {
                IgnoreFileSize = true,
            });

            // Fix RAW color
            settings.SetDefines(new DngReadDefines()
            {
                UseCameraWhitebalance = true,
                OutputColor           = DngOutputColor.AdobeRGB,
                ReadThumbnail         = true,
            });

            #endregion


            #region Read image data
            switch (ext)
            {
            case ".TXT":     // base64 string
            case ".B64":
                var base64Content = string.Empty;
                using (var fs = new StreamReader(filename)) {
                    base64Content = fs.ReadToEnd();
                }

                bitmap = ConvertBase64ToBitmap(base64Content);
                break;


            case ".GIF":
            case ".FAX":
                // Note: Using FileStream is much faster than using MagickImageCollection

                try {
                    bitmap = ConvertFileToBitmap(filename);
                }
                catch {
                    // #637: falls over with certain images, fallback to MagickImage
                    ReadWithMagickImage();
                }
                break;


            default:
                ReadWithMagickImage();

                break;
            }
            #endregion


            #region Internal Functions

            // Preprocess magick image
            (IExifProfile, IColorProfile) PreprocesMagickImage(MagickImage imgM, bool checkRotation = true)
            {
                imgM.Quality = quality;

                IColorProfile imgColorProfile = null;
                IExifProfile  profile         = null;

                try {
                    // get the color profile of image
                    imgColorProfile = imgM.GetColorProfile();

                    // Get Exif information
                    profile = imgM.GetExifProfile();
                }
                catch { }

                // Use embedded thumbnails if specified
                if (profile != null && useEmbeddedThumbnail)
                {
                    // Fetch the embedded thumbnail
                    using var thumbM = profile.CreateThumbnail();
                    if (thumbM != null)
                    {
                        bitmap = thumbM.ToBitmap();
                    }
                }

                // Revert to source image if an embedded thumbnail with required size was not found.
                if (bitmap == null)
                {
                    if (profile != null && checkRotation)
                    {
                        // Get Orientation Flag
                        var exifRotationTag = profile.GetValue(ExifTag.Orientation);

                        if (exifRotationTag != null)
                        {
                            if (int.TryParse(exifRotationTag.Value.ToString(), out var orientationFlag))
                            {
                                var orientationDegree = Helpers.GetOrientationDegree(orientationFlag);
                                if (orientationDegree != 0)
                                {
                                    //Rotate image accordingly
                                    imgM.Rotate(orientationDegree);
                                }
                            }
                        }
                    }

                    // if always apply color profile
                    // or only apply color profile if there is an embedded profile
                    if (isApplyColorProfileForAll || imgColorProfile != null)
                    {
                        var imgColor = Helpers.GetColorProfile(colorProfileName);

                        if (imgColor != null)
                        {
                            imgM.TransformColorSpace(
                                //set default color profile to sRGB
                                imgColorProfile ?? ColorProfile.SRGB,
                                imgColor);
                        }
                    }
                }

                return(profile, imgColorProfile);
            }

            void ReadWithMagickImage()
            {
                var checkRotation = ext != ".HEIC";

                using var imgColl = new MagickImageCollection();

                // Issue #530: ImageMagick falls over if the file path is longer than the (old) windows limit of 260 characters. Workaround is to read the file bytes, but that requires using the "long path name" prefix to succeed.
                if (filename.Length > 260)
                {
                    var newFilename = Helpers.PrefixLongPath(filename);
                    var allBytes    = File.ReadAllBytes(newFilename);

                    imgColl.Ping(allBytes, settings);
                }
                else
                {
                    imgColl.Ping(filename, settings);
                }


                if (imgColl.Count > 1 && forceLoadFirstPage is false)
                {
                    imgColl.Read(filename, settings);
                    foreach (var imgPageM in imgColl)
                    {
                        (exif, colorProfile) = PreprocesMagickImage((MagickImage)imgPageM, checkRotation);
                    }

                    bitmap = imgColl.ToBitmap();
                    return;
                }


                using var imgM = new MagickImage();
                if (useRawThumbnail is true)
                {
                    var profile = imgColl[0].GetProfile("dng:thumbnail");

                    try {
                        // try to get thumbnail
                        imgM.Read(profile?.GetData(), settings);
                    }
                    catch {
                        imgM.Read(filename, settings);
                    }
                }
                else
                {
                    imgM.Read(filename, settings);
                }


                // Issue #679: fix targa display with Magick.NET 7.15.x
                if (ext == ".TGA")
                {
                    imgM.AutoOrient();
                }


                imgM.Quality         = quality;
                (exif, colorProfile) = PreprocesMagickImage(imgM, checkRotation);

                using var channelImgM = ApplyColorChannel(imgM, channel);
                bitmap = channelImgM.ToBitmap();
            }

            #endregion


            return(new ImgData()
            {
                Image = bitmap,
                Exif = exif,
                ColorProfile = colorProfile,
            });
        }