/// <summary>
        /// Returns the thumbnail in the exif profile when available.
        /// </summary>
        /// <param name="self">The exif profile.</param>
        /// <returns>The thumbnail in the exif profile when available.</returns>
        public static IMagickImage <QuantumType> CreateThumbnail(this IExifProfile self)
        {
            if (self is null)
            {
                throw new Exception($"{nameof(self)} is null.");
            }

            var thumbnailLength = self.ThumbnailLength;
            var thumbnailOffset = self.ThumbnailOffset;

            if (thumbnailLength == 0 || thumbnailOffset == 0)
            {
                return(null);
            }

            var data = self.GetData();

            if (data == null || data.Length < (thumbnailOffset + thumbnailLength))
            {
                return(null);
            }

            var result = new byte[thumbnailLength];

            Array.Copy(data, thumbnailOffset, result, 0, thumbnailLength);

            return(new MagickImage(result));
        }
示例#2
0
        private static void TestExifProfile(IExifProfile profile)
        {
            Assert.NotNull(profile);

            Assert.Equal(44, profile.Values.Count());

            foreach (var value in profile.Values)
            {
                Assert.NotNull(value.GetValue());

                if (value.Tag == ExifTag.Software)
                {
                    Assert.Equal("Adobe Photoshop 7.0", value.ToString());
                }

                if (value.Tag == ExifTag.XResolution)
                {
                    Assert.Equal(new Rational(300, 1), (Rational)value.GetValue());
                }

                if (value.Tag == ExifTag.GPSLatitude)
                {
                    Rational[] pos = (Rational[])value.GetValue();
                    Assert.Equal(54, pos[0].ToDouble());
                    Assert.Equal(59.38, pos[1].ToDouble());
                    Assert.Equal(0, pos[2].ToDouble());
                }

                if (value.Tag == ExifTag.ShutterSpeedValue)
                {
                    Assert.Equal(9.5, ((SignedRational)value.GetValue()).ToDouble());
                }
            }
        }
示例#3
0
        public void Execute(PipelineContext context, MagickImage magickImage)
        {
            StringInterpolator interpolator = Interpolator.Branch(context.ResolvedData, magickImage);
            IExifProfile       exifProfile  = magickImage.GetExifProfile() ?? new ExifProfile();

            IEnumerable <TagConfig <ExifTag> > tags = new List <TagConfig <ExifTag> >();

            if (Config.Defaults)
            {
                tags = tags.Concat(DefaultExifTags);
            }

            if (Config.Exif != null)
            {
                tags = tags.Concat(Config.Exif);
            }

            foreach (TagConfig <ExifTag> tag in tags)
            {
                string value = interpolator.Interpolate(tag.Value);
                exifProfile.SetValue((ExifTag <string>)tag.Tag, value);
            }

            magickImage.SetProfile(exifProfile);
            context.Next(magickImage);
        }
示例#4
0
        private static void TestValue <T>(IExifProfile profile, ExifTag <T> tag, string expectedValue)
        {
            var value = profile.GetValue(tag);

            Assert.IsNotNull(value);
            Assert.AreEqual(expectedValue, value.Value);
        }
示例#5
0
        /// <summary>
        /// persist existing metadata values (if any) to property values
        /// </summary>
        private void Init()
        {
            IExifProfile exifprofile = _image.GetExifProfile();

            if (!exifprofile.IsNull())
            {
                if (exifprofile.GetValue(ExifTag.Copyright) != null)
                {
                    Copyright = exifprofile.GetValue(ExifTag.Copyright).ToString();
                }
                if (exifprofile.GetValue(ExifTag.Artist) != null)
                {
                    Creator = exifprofile.GetValue(ExifTag.Artist).ToString();
                }
                if (exifprofile.GetValue(ExifTag.ImageDescription) != null)
                {
                    Subject = exifprofile.GetValue(ExifTag.ImageDescription).ToString();
                }
                if (exifprofile.GetValue(ExifTag.Software) != null)
                {
                    Software = exifprofile.GetValue(ExifTag.Software).ToString();
                }
            }
            IIptcProfile iptcprofile = _image.GetIptcProfile();

            if (!iptcprofile.IsNull())
            {
                if (iptcprofile.GetValue(IptcTag.Country) != null)
                {
                    Country = iptcprofile.GetValue(IptcTag.Country).ToString();
                }
                if (iptcprofile.GetValue(IptcTag.Headline) != null)
                {
                    Headline = iptcprofile.GetValue(IptcTag.Headline).ToString();
                }
                if (iptcprofile.GetValue(IptcTag.Keyword) != null)
                {
                    Keywords = iptcprofile.GetValue(IptcTag.Keyword).ToString();
                }
                if (iptcprofile.GetValue(IptcTag.Source) != null)
                {
                    Source = iptcprofile.GetValue(IptcTag.Source).ToString();
                }
                if (iptcprofile.GetValue(IptcTag.Caption) != null)
                {
                    Subject = iptcprofile.GetValue(IptcTag.Caption).ToString();
                }
                if (iptcprofile.GetValue(IptcTag.Title) != null)
                {
                    Title = iptcprofile.GetValue(IptcTag.Title).ToString();
                }
            }
        }
示例#6
0
        public static void CreateThumbnailFromExifData()
        {
            // Read image from file
            using (MagickImage image = new MagickImage(SampleFiles.FujiFilmFinePixS1ProJpg))
            {
                // Retrieve the exif information
                IExifProfile profile = image.GetExifProfile();

                // Create thumbnail from exif information
                using (IMagickImage thumbnail = profile.CreateThumbnail())
                {
                    // Check if exif profile contains thumbnail and save it
                    if (thumbnail != null)
                    {
                        thumbnail.Write(SampleFiles.OutputDirectory + "FujiFilmFinePixS1Pro.thumb.jpg");
                    }
                }
            }
        }
        public string Execute(FileItem item, string infile, string dest, ValuePairEnumerator configData)
        {
            var conf = new RotateTransformViewModel(configData);

            // Read from file
            using (MagickImage image = new MagickImage(infile))
            {
                image.BackgroundColor = new MagickColor(Color.Black.R, Color.Black.G, Color.Black.B);
                if (conf.ManualRotate)
                {
                    image.Rotate(item.RotationAngle);
                }
                else
                {
                    if (conf.AutoRotate)
                    {
                        IExifProfile profile = image.GetExifProfile();
                        image.AutoOrient();
                        profile.SetValue(ExifTag.Orientation, (UInt16)0);
                    }
                }
                if (conf.Angle > 0)
                {
                    image.Rotate(conf.Angle);
                }

                if (conf.FlipHorizontal)
                {
                    image.Flop();
                }

                if (conf.FlipVertical)
                {
                    image.Flip();
                }

                image.Format = MagickFormat.Jpeg;
                // Save the result
                image.Write(dest);
            }
            return(dest);
        }
示例#8
0
        public static JObject Read(Stream stream)
        {
            // Read image from file
            using MagickImage image = new(stream);
            // Retrieve the exif information
            IExifProfile profile = image.GetExifProfile();

            // Check if image contains an exif profile
            if (profile == null)
            {
                return(new JObject(new JProperty("warning", "Image does not contain exif information.")));
            }

            JObject           metadata   = new();
            IList <JProperty> properties = new List <JProperty>();

            // Write all values to the console
            foreach (IExifValue value in profile.Values)
            {
                string    name = value.Tag.ToString();
                JProperty property;
                if (!value.IsArray)
                {
                    property = name switch
                    {
                        "DateTime" or "DateTimeDigitized" or "DateTimeOriginal" => Transformer.Transform(TransformType.DateTime, value),
                        _ => Transformer.Transform(TransformType.String, value)
                    };
                }
                else
                {
                    property = value.ToString() switch
                    {
                        "ImageMagick.ExifByteArray" =>
                        name switch
                        {
                            "ComponentsConfiguration" => Transformer.Transform(TransformType.ComponentsConfiguration, value),
                            "GPSVersionID" => Transformer.Transform(TransformType.ByteVersion, value),
                            _ => Transformer.Transform(TransformType.ByteArray, value)
                        },
示例#9
0
        public static void ReadExifData()
        {
            // Read image from file
            using (MagickImage image = new MagickImage(SampleFiles.FujiFilmFinePixS1ProJpg))
            {
                // Retrieve the exif information
                IExifProfile profile = image.GetExifProfile();

                // Check if image contains an exif profile
                if (profile == null)
                {
                    Console.WriteLine("Image does not contain exif information.");
                }
                else
                {
                    // Write all values to the console
                    foreach (IExifValue value in profile.Values)
                    {
                        Console.WriteLine("{0}({1}): {2}", value.Tag, value.DataType, value.ToString());
                    }
                }
            }
        }
示例#10
0
        /// <summary>
        /// 찍은 날짜 기준으로 폴더 생성 후 파일 분류
        /// </summary>
        /// <param name="filePath">파일 경로</param>
        /// <param name="trgDirPath">저장 경로</param>
        static private void FileByDateTimeOriginal(string filePath, string trgDirPath)
        {
            using (MagickImage img = new MagickImage(filePath))
            {
                string dateTime = null;

                IExifProfile profile = img.GetExifProfile();

                foreach (IExifValue value in profile.Values)
                {
                    if (value.Tag.ToString() == "DateTimeOriginal")
                    {
                        Console.WriteLine("{0}({1}): {2}", value.Tag, value.DataType, value.ToString());
                        dateTime = value.ToString();
                    }
                }

                if (dateTime != null)
                {
                    string[] dateTimes   = dateTime.Split();
                    string   date        = dateTimes[0].Replace(":", ".");
                    string   saveDirPath = Path.Combine(trgDirPath, date);

                    DirectoryInfo saveDir = new DirectoryInfo(saveDirPath);
                    FileInfo      imgFile = new FileInfo(filePath);

                    if (!saveDir.Exists)
                    {
                        saveDir.Create();
                    }

                    string saveFilePath = Path.Combine(saveDirPath, Path.GetFileName(filePath));
                    imgFile.MoveTo(saveFilePath);
                }
            }
        }
        /// <summary>
        /// Returns the thumbnail in the exif profile when available.
        /// </summary>
        /// <param name="self">The exif profile.</param>
        /// <returns>The thumbnail in the exif profile when available.</returns>
        public static IMagickImage <QuantumType> CreateThumbnail(this IExifProfile self)
        {
            Throw.IfNull(nameof(self), self);

            var thumbnailLength = self.ThumbnailLength;
            var thumbnailOffset = self.ThumbnailOffset;

            if (thumbnailLength == 0 || thumbnailOffset == 0)
            {
                return(null);
            }

            var data = self.GetData();

            if (data.Length < (thumbnailOffset + thumbnailLength))
            {
                return(null);
            }

            var result = new byte[thumbnailLength];

            Array.Copy(data, thumbnailOffset, result, 0, thumbnailLength);
            return(new MagickImage(result));
        }
示例#12
0
    protected void btnTest_Click(object sender, EventArgs e)
    {
        StringBuilder sb = new StringBuilder();

        foreach (Controls_mfbFileUpload fu in mfbMultiFileUpload1.FileUploadControls)
        {
            if (fu.HasFile)
            {
                sb.AppendFormat(CultureInfo.InvariantCulture, "<hr /><br />File: {0}<br />", fu.PostedFile.FileName);
                IMagickImage image = new MagickImage(fu.PostedFile.InputStream);
                IExifProfile exif  = image.GetExifProfile();

                if (exif == null)
                {
                    continue;
                }

                // Write all values to the console
                foreach (IExifValue value in exif.Values)
                {
                    if (value.IsArray)
                    {
                        List <string> lst        = new List <string>();
                        object        o          = value.GetValue();
                        byte[]        rgbyte     = o as byte[];
                        ushort[]      rgshort    = o as ushort[];
                        Rational[]    rgrational = o as Rational[];

                        if (rgbyte != null)
                        {
                            foreach (byte b in rgbyte)
                            {
                                lst.Add(b.ToString("X", CultureInfo.InvariantCulture));
                            }
                        }
                        else if (rgshort != null)
                        {
                            foreach (ushort u in rgshort)
                            {
                                lst.Add(u.ToString(CultureInfo.InvariantCulture));
                            }
                        }
                        else if (rgrational != null)
                        {
                            foreach (Rational r in rgrational)
                            {
                                lst.Add(r.ToString(CultureInfo.InvariantCulture));
                            }
                        }
                        else
                        {
                            lst.Add(o.ToString());
                        }

                        sb.AppendFormat(CultureInfo.CurrentCulture, "{0}({1}): [{2}]<br />", value.Tag, value.DataType, String.Join(", ", lst));
                    }
                    else
                    {
                        sb.AppendFormat(CultureInfo.CurrentCulture, "{0}({1}): {2}<br />", value.Tag, value.DataType, value.ToString());
                    }
                }
            }
        }

        lblDiagnose.Text = sb.ToString();
    }
示例#13
0
        private void UpdateExif(ImageInfo imginfo, IExifProfile profile)
        {
            bool isnorth  = true;
            bool iseast   = true;
            bool abovesea = true;

            foreach (IExifValue value in profile.Values)
            {
                if (string.Compare(value.Tag.ToString(), "Make", true, CultureInfo.InvariantCulture) == 0)
                {
                    imginfo.Make = (string)value.GetValue();
                }
                else if (string.Compare(value.Tag.ToString(), "Model", true, CultureInfo.InvariantCulture) == 0)
                {
                    imginfo.Model = (string)value.GetValue();
                }
                else if (string.Compare(value.Tag.ToString(), "Software", true, CultureInfo.InvariantCulture) == 0)
                {
                    imginfo.Software = (string)value.GetValue();
                }
                else if (string.Compare(value.Tag.ToString(), "LensMake", true, CultureInfo.InvariantCulture) == 0)
                {
                    imginfo.LensMake = (string)value.GetValue();
                }
                else if (string.Compare(value.Tag.ToString(), "LensModel", true, CultureInfo.InvariantCulture) == 0)
                {
                    imginfo.LensModel = (string)value.GetValue();
                }
                else if (string.Compare(value.Tag.ToString(), "DateTime", true, CultureInfo.InvariantCulture) == 0)
                {
                    imginfo.StrExifDateTime = (string)value.GetValue();
                    imginfo.ExifDateTime    = ParseDatetime(imginfo.StrExifDateTime);
                }
                else if (string.Compare(value.Tag.ToString(), "DateTimeOriginal", true, CultureInfo.InvariantCulture) == 0)
                {
                    if (string.IsNullOrWhiteSpace(imginfo.StrExifDateTime))
                    {
                        imginfo.StrExifDateTime = (string)value.GetValue();
                        imginfo.ExifDateTime    = ParseDatetime(imginfo.StrExifDateTime);
                    }
                }
                else if (string.Compare(value.Tag.ToString(), "DateTimeDigitized", true, CultureInfo.InvariantCulture) == 0)
                {
                    if (string.IsNullOrWhiteSpace(imginfo.StrExifDateTime))
                    {
                        imginfo.StrExifDateTime = (string)value.GetValue();
                        imginfo.ExifDateTime    = ParseDatetime(imginfo.StrExifDateTime);
                    }
                }
                else if (string.Compare(value.Tag.ToString(), "GPSLatitudeRef", true, CultureInfo.InvariantCulture) == 0)
                {
                    var n = (string)value.GetValue();
                    if (string.Compare(n, "N", true, CultureInfo.InvariantCulture) == 0)
                    {
                        isnorth = true;
                    }
                    else
                    {
                        isnorth = false;
                    }
                }
                else if (string.Compare(value.Tag.ToString(), "GPSLatitude", true, CultureInfo.InvariantCulture) == 0)
                {
                    var    rs = (Rational[])value.GetValue();
                    double v  = 0;
                    int    e  = 1;
                    for (int i = 0; i < rs.Length; i++)
                    {
                        v += ((double)rs[i].Numerator) / (rs[i].Denominator * e);
                        e *= 60;
                    }
                    imginfo.Latitude = v;
                }
                else if (string.Compare(value.Tag.ToString(), "GPSLongitudeRef", true, CultureInfo.InvariantCulture) == 0)
                {
                    var e = (string)value.GetValue();
                    if (string.Compare(e, "E", true, CultureInfo.InvariantCulture) == 0)
                    {
                        iseast = true;
                    }
                    else
                    {
                        iseast = false;
                    }
                }
                else if (string.Compare(value.Tag.ToString(), "GPSLongitude", true, CultureInfo.InvariantCulture) == 0)
                {
                    var    rs = (Rational[])value.GetValue();
                    double v  = 0;
                    int    e  = 1;
                    for (int i = 0; i < rs.Length; i++)
                    {
                        v += ((double)rs[i].Numerator) / (rs[i].Denominator * e);
                        e *= 60;
                    }
                    imginfo.Longitude = v;
                }
                else if (string.Compare(value.Tag.ToString(), "GPSAltitudeRef", true, CultureInfo.InvariantCulture) == 0)
                {
                    var e = (byte)value.GetValue();
                    if (e == 0)
                    {
                        abovesea = true;
                    }
                    else
                    {
                        abovesea = false;
                    }
                }
                else if (string.Compare(value.Tag.ToString(), "GPSAltitude", true, CultureInfo.InvariantCulture) == 0)
                {
                    var rs = (Rational)value.GetValue();
                    imginfo.Altitude = ((double)rs.Numerator) / rs.Denominator;
                }
            }
            if (imginfo.Latitude != null)
            {
                if (!isnorth)
                {
                    imginfo.Latitude = 0 - imginfo.Latitude;
                }
            }
            if (imginfo.Longitude != null)
            {
                if (!iseast)
                {
                    imginfo.Longitude = 0 - imginfo.Longitude;
                }
            }
            if (imginfo.Altitude != null)
            {
                if (!abovesea)
                {
                    imginfo.Altitude = 0 - imginfo.Altitude;
                }
            }
            if (imginfo.ExifDateTime != null)
            {
                imginfo.MediaTime = imginfo.ExifDateTime.Value;
            }
            _dbConnection.Update(imginfo);
        }
示例#14
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,
            });
        }
示例#15
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="useEmbeddedThumbnails">Return the embedded thumbnail if required size was not found.</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 useEmbeddedThumbnails = 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;
            }

            if (size.Width > 0 && size.Height > 0)
            {
                settings.Width  = size.Width;
                settings.Height = size.Height;
            }
            #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();
                    fs.Close();
                }

                bitmap = ConvertBase64ToBitmap(base64Content);
                break;

            case ".GIF":
            case ".TIF":
                // 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;

            case ".ICO":
            case ".WEBP":
                using (var imgColl = new MagickImageCollection(filename, settings)) {
                    bitmap = imgColl.ToBitmap();
                }
                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 && useEmbeddedThumbnails)
                {
                    // Fetch the embedded thumbnail
                    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)
                    {
                        if (imgColorProfile != null)
                        {
                            // correct the image color space
                            imgM.ColorSpace = imgColorProfile.ColorSpace;
                        }
                        else
                        {
                            // set default color profile and color space
                            imgM.SetProfile(ColorProfile.SRGB);
                            imgM.ColorSpace = ColorProfile.SRGB.ColorSpace;
                        }

                        var imgColor = Helpers.GetColorProfile(colorProfileName);
                        if (imgColor != null)
                        {
                            imgM.SetProfile(imgColor);
                            imgM.ColorSpace = imgColor.ColorSpace;
                        }
                    }
                }


                return(profile, imgColorProfile);
            }

            // Separate color channel
            MagickImage ApplyColorChannel(MagickImage imgM)
            {
                if (channel != -1)
                {
                    var magickChannel = (Channels)channel;
                    var channelImgM   = (MagickImage)imgM.Separate(magickChannel).First();

                    if (imgM.HasAlpha && magickChannel != Channels.Alpha)
                    {
                        using (var alpha = imgM.Separate(Channels.Alpha).First()) {
                            channelImgM.Composite(alpha, CompositeOperator.CopyAlpha);
                        }
                    }

                    return(channelImgM);
                }

                return(imgM);
            }

            void ReadWithMagickImage()
            {
                MagickImage imgM;

                // 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);

                    imgM = new MagickImage(allBytes, settings);
                }
                else
                {
                    imgM = new MagickImage(filename, settings);
                }


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

                var checkRotation = ext != ".HEIC";

                (exif, colorProfile) = PreprocesMagickImage(imgM, checkRotation);

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


                imgM.Dispose();
            }

            #endregion


            return(new ImgData()
            {
                Image = bitmap,
                Exif = exif,
                ColorProfile = colorProfile,
            });
        }
示例#16
0
        private void FrmInformation_Load(object sender, EventArgs e)
        {
            var state = Program.State;

            //file
            dgvFile.Rows.Add("Name", state.ActiveEntry.Name);

            //image relation
            dgvFile.Rows.Add("Dimensions", String.Format("{0} x {1}", state.NativeImage.BaseWidth, state.NativeImage.BaseHeight));
            dgvFile.Rows.Add("Format", state.NativeImage.Format.ToString());
            dgvFile.Rows.Add("Color Space", state.NativeImage.ColorSpace.ToString());
            dgvFile.Rows.Add("Color Type", state.NativeImage.ColorType.ToString());
            //dgvFile.Rows.Add("Unique colors", workingData.nativeImage.TotalColors.ToString() );  //very slow


            //file related
            dgvFile.Rows.Add("Size (bytes)", state.ActiveEntry.Length.ToString());
            dgvFile.Rows.Add("Created", state.ActiveEntry.CreationTime.ToString());
            dgvFile.Rows.Add("Last Written", state.ActiveEntry.LastWriteTime.ToString());
            dgvFile.Rows.Add("Path", state.ActiveEntry.DirectoryName);

            IExifProfile profile = state.NativeImage.GetExifProfile();

            if (profile != null)
            {
                foreach (IExifValue value in profile.Values)
                {
                    dgvExif.Rows.Add(value.Tag.ToString(), value.ToString());
                }
            }


            //            propValue = BitConverter.ToUInt16(property.Value, 0);
            //            break;
            //        case PropertyTagType.SLONG:
            //            propValue = BitConverter.ToInt32(property.Value, 0);
            //            break;
            //        case PropertyTagType.Int32:
            //            propValue = BitConverter.ToUInt32(property.Value, 0);
            //            break;
            //        case PropertyTagType.SRational:
            //            int sdividend = BitConverter.ToInt32(property.Value, 0);
            //            int sdivisor = BitConverter.ToInt32(property.Value, 4);
            //            if (sdivisor == 0)
            //            {
            //                propValue = double.NaN;
            //            }
            //            else
            //            {
            //                propValue = Math.Round(((double)sdividend / (double)sdivisor), 1);
            //            }
            //            break;
            //        case PropertyTagType.Rational:
            //            uint dividend = BitConverter.ToUInt32(property.Value, 0);
            //            uint divisor = BitConverter.ToUInt32(property.Value, 4);
            //            if(divisor == 0)
            //            {
            //                propValue = double.NaN;
            //            }
            //            else
            //            {
            //                propValue = Math.Round( ((double)dividend / (double)divisor), 1);
            //            }
            //            break;
            //        case PropertyTagType.Undefined:
            //        default:
            //            propValue = String.Empty;
            //            break;
            //    }

            //    dgvExif.Rows.Add((PropertyTagId)property.Id, propValue.ToString());
            //}
        }