public static UInt16 RotateImageViaInPlaceBitmapMetadataWriter(string filename, UInt16 prevOrient)
        {
            // InPlaceBitmapMetadataWriter allows us to modify the metadata (exif) directly to the original file (without a temp file)
            // assuming there is enough space, otherwise padding must be added.  For orientation the space is constant, so it should
            // always work if the orientation field already exists
            UInt16 orient = 1;

            orient = (UInt16)GetNextRotationOrientation(prevOrient); // get new rotation

            // This only works for jpg photos
            if (!filename.EndsWith("jpg"))
            {
                Console.WriteLine("The file you passed in is not a JPEG.");
                throw new ArgumentException("The file you passed in is not a JPEG:\n " + filename, "filename");
            }

            // This code is based on http://blogs.msdn.com/b/rwlodarc/archive/2007/07/18/using-wpf-s-inplacebitmapmetadatawriter.aspx
            using (Stream originalFile = File.Open(filename, FileMode.Open, FileAccess.ReadWrite))
            {
                ConsoleColor originalColor = Console.ForegroundColor;

                BitmapDecoder output = BitmapDecoder.Create(originalFile, BitmapCreateOptions.None, BitmapCacheOption.Default);

                InPlaceBitmapMetadataWriter metadata = output.Frames[0].CreateInPlaceBitmapMetadataWriter();

                // Within the InPlaceBitmapMetadataWriter, you can add, update, or remove metadata.
                if (!metadata.ContainsQuery("/app1"))
                {
                    metadata.SetQuery("/app1", new BitmapMetadata("app1"));
                }
                if (!metadata.ContainsQuery("/app1/{ushort=0}"))
                {
                    metadata.SetQuery("/app1/{ushort=0}", new BitmapMetadata("ifd"));
                }
                metadata.SetQuery("/app1/{ushort=0}/{ushort=274}", orient); //set next rotation

                if (metadata.TrySave())
                {
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine("InPlaceMetadataWriter succeeded!");
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("InPlaceMetadataWriter failed!");
                    throw new Exception("Rotate Image failed. Try to 'S' (Show in Folder) and manually rotate it.");
                }

                Console.ForegroundColor = originalColor;

                return(orient);
            }
        }
예제 #2
0
        private void CreateAndShowMainWindow()
        {
            // Create the application's main window
            mainWindow       = new Window();
            mainWindow.Title = "Image Metadata";

            // <SnippetSetQuery>
            Stream                      pngStream  = new System.IO.FileStream("smiley.png", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
            PngBitmapDecoder            pngDecoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapFrame                 pngFrame   = pngDecoder.Frames[0];
            InPlaceBitmapMetadataWriter pngInplace = pngFrame.CreateInPlaceBitmapMetadataWriter();

            if (pngInplace.TrySave() == true)
            {
                pngInplace.SetQuery("/Text/Description", "Have a nice day.");
            }
            pngStream.Close();
            // </SnippetSetQuery>

            // Draw the Image
            Image myImage = new Image();

            myImage.Source  = new BitmapImage(new Uri("smiley.png", UriKind.Relative));
            myImage.Stretch = Stretch.None;
            myImage.Margin  = new Thickness(20);

            // <SnippetGetQuery>

            // Add the metadata of the bitmap image to the text block.
            TextBlock myTextBlock = new TextBlock();

            myTextBlock.Text = "The Description metadata of this image is: " + pngInplace.GetQuery("/Text/Description").ToString();
            // </SnippetGetQuery>

            // Define a StackPanel to host Controls
            StackPanel myStackPanel = new StackPanel();

            myStackPanel.Orientation         = Orientation.Vertical;
            myStackPanel.Height              = 200;
            myStackPanel.VerticalAlignment   = VerticalAlignment.Top;
            myStackPanel.HorizontalAlignment = HorizontalAlignment.Center;

            // Add the Image and TextBlock to the parent Grid
            myStackPanel.Children.Add(myImage);
            myStackPanel.Children.Add(myTextBlock);

            // Add the StackPanel as the Content of the Parent Window Object
            mainWindow.Content = myStackPanel;
            mainWindow.Show();
        }
예제 #3
0
        // ReSharper disable once InconsistentNaming
        public static void WriteIPTC(string filename, IIPTCModel iptc)
        {
            Console.WriteLine($"{iptc.ByLine} {iptc.Caption} {iptc.CopyrightNotice} {iptc.Headline} {iptc.Keywords}");

            string filePath = Path.Combine(Constants.PicPath, filename);

            using (Stream fs = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                JpegBitmapDecoder decoder = new JpegBitmapDecoder(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
                BitmapFrame       frame   = decoder.Frames[0];
                var metadata = frame.Metadata.Clone() as BitmapMetadata;
                InPlaceBitmapMetadataWriter jpgInPlace = frame.CreateInPlaceBitmapMetadataWriter();
                if (jpgInPlace != null)
                {
                    jpgInPlace.SetQuery(@"/app13/irb/8bimiptc/iptc/caption", iptc.Caption);
                    jpgInPlace.SetQuery(@"/app13/irb/8bimiptc/iptc/keywords", iptc.Keywords);
                    jpgInPlace.SetQuery(@"/app13/irb/8bimiptc/iptc/by-line", iptc.ByLine);
                    jpgInPlace.SetQuery(@"/app13/irb/8bimiptc/iptc/copyright notice", iptc.CopyrightNotice);
                    jpgInPlace.SetQuery(@"/app13/irb/8bimiptc/iptc/headline", iptc.Headline);
                }
                fs.Close();
            }
        }
예제 #4
0
        public void SaveBitmap(Bitmap bitmap)
        {
            const string filetype = ".png";
            string       filename = DateTime.Today.Year.ToString() + "_" + DateTime.Today.Month.ToString() + "_" + DateTime.Today.Day.ToString();

            filename = Path.Combine(screenshotFolder, filename);
            if (File.Exists(filename + filetype))
            {
                var ExistingImage = Image.FromFile(filename + filetype);
                int n             = 1;
                while (File.Exists(filename + "(" + n.ToString() + ")" + filetype))
                {
                    n++;
                }
                filename += "(" + n.ToString() + ")";
            }
            //FileStream stream = new FileStream(filename + ".png",  FileMode.CreateNew);

            var prop = (PropertyItem)FormatterServices.GetUninitializedObject(typeof(PropertyItem));

            prop.Id    = 37510;
            prop.Type  = 2;
            prop.Value = Encoding.UTF8.GetBytes("Hello World!");
            prop.Len   = prop.Value.Length;
            bitmap.SetPropertyItem(prop);
            bitmap.Save(filename + filetype);
            BitmapMetadata data;

            //FileStream stream = new FileStream(filename + filetype, FileMode.Create);
            //BitmapMetadata myBitmapMetadata = new BitmapMetadata("jpeg");
            //myBitmapMetadata.Comment = "this is a comment";
            //var encoder3 = new JpegBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);

            Stream                      pngStream  = new FileStream(filename + filetype, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
            PngBitmapDecoder            pngDecoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapFrame                 pngFrame   = pngDecoder.Frames[0];
            InPlaceBitmapMetadataWriter pngInplace = pngFrame.CreateInPlaceBitmapMetadataWriter();

            if (pngInplace.TrySave() == true)
            {
                pngInplace.SetQuery("/Text/Description", "Have a nice day.");
            }
            pngStream.Close();
            //ImageMetadata metadata = new ImageMetadata("blah","erik","fractal","this is a comment");
            //SaveEXIFMetadata(bitmap, metadata, filename + ".jpeg");
            //SaveEXIFMetadataProperty(bitmap,"hello", filename + ".png");
        }
예제 #5
0
        //ajouter des metadata au images
        public void AddTags(string filename, string[] tags)
        {
            //ouvre un stream pour l'image
            using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
            {
                //decode l'image pour récupérer les metadata
                BitmapDecoder decoder = BitmapDecoder.Create(fs, BitmapCreateOptions.None, BitmapCacheOption.None);

                // saisi les frames bitmap, qui contiennent les metadata
                BitmapFrame frame = decoder.Frames[0];

                // obtiens les metadata en tant que BitmapMetadata
                BitmapMetadata metadata = frame.Metadata as BitmapMetadata;

                // instancie InPlaceBitmapMetadataWriter pour écrire les metadata dans l'image
                InPlaceBitmapMetadataWriter writer = frame.CreateInPlaceBitmapMetadataWriter();

                string[] keys;

                //si des metadata existent déjà
                if (metadata.Keywords != null)
                {
                    //créé la liste complète des tags, vieux et nouveau
                    keys = new string[metadata.Keywords.Count + tags.Length];

                    //récupère les valeurs des textbox

                    var tag2 = TagWriter2.Text;
                    int i    = 0;

                    //récupère la valeur des mots clé existant
                    foreach (string keyword in metadata.Keywords)
                    {
                        keys[i] = keyword;
                        i++;
                    }

                    // récupère la valeur des nouveaus mots clé
                    foreach (string tag in tags)
                    {
                        keys[i] = tag;
                        i++;
                    }


                    //écrit les nouvelles metadata dans l'image
                    writer.SetQuery("System.Keywords", keys);
                    writer.SetQuery("System.Author", tag2);
                }

                //si il n'y a pas de metadata existante
                else
                {
                    keys = tags;
                    //récupère les valeurs des textbox
                    var Tag  = TagWriter.Text;
                    var tag2 = TagWriter2.Text;

                    //écrit les nouvelles metadata dans l'image
                    writer.SetQuery("System.Title", Tag);
                    writer.SetQuery("System.Author", tag2);
                }

                //si il n'y a pas d'espace pour stocké les nouvelles metadata
                if (!writer.TrySave())
                {
                    fs.Close();
                    fs.Dispose();
                    string test = TagWriter.Text;
                    SetUpMetadataOnImage(filename, test);
                }
            }
        }
    public static void SetImageMetadata(string imagesFolderPath)
    {
        string originalPath = @"C:\Users\test\Desktop\test.jpg";
        string outputPath   = Environment.CurrentDirectory + @"\output.jpg";
        string finalPath    = Environment.CurrentDirectory + @"\output_beforeInPlaceBitmapMetadataWriter.jpg";
        BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;
        uint paddingAmount = 2048;     // 2Kb padding for this example, but really this can be any value.

        // Our recommendation is to keep this between 1Kb and 5Kb as most metadata updates are not large.
        // High level overview:
        //   1. Perform a lossles transcode on the JPEG
        //   2. Add appropriate padding
        //   3. Optionally add whatever metadata we need to add initially
        //   4. Save the file
        //   5. For sanity, we verify that we really did a lossless transcode
        //   6. Open the new file and add metadata in-place
        using (Stream originalFile = File.Open(originalPath, FileMode.Open, FileAccess.Read))
        {
            // Notice the BitmapCreateOptions and BitmapCacheOption. Using these options in the manner here
            // will inform the JPEG decoder and encoder that we're doing a lossless transcode operation. If the
            // encoder is anything but a JPEG encoder, then this no longer is a lossless operation.
            // ( Details: Basically BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile
            //   tell the decoder to use the original image bits and BitmapCacheOption.None tells the decoder to wait
            //   with decoding. So, at the time of encoding the JPEG encoder understands that the input was a JPEG
            //   and just copies over the image bits without decompressing and recompressing them. Hence, this is a
            //   lossless operation. )
            BitmapDecoder original = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None);
            if (!original.CodecInfo.FileExtensions.Contains("jpg"))
            {
                Console.WriteLine("The file you passed in is not a JPEG.");
                return;
            }
            JpegBitmapEncoder output = new JpegBitmapEncoder();
            // If you're just interested in doing a lossless transcode without adding metadata, just do this:
            //output.Frames = original.Frames;
            // If you want to add metadata to the image using the InPlaceBitmapMetadataWriter, first add padding:
            if (original.Frames[0] != null && original.Frames[0].Metadata != null)
            {
                // Your gut feel may want you to do something like:
                //     output.Frames = original.Frames;
                //     BitmapMetadata metadata = output.Frames[0].Metadata as BitmapMetadata;
                //     if (metadata != null)
                //     {
                //         metadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount);
                //     }
                // However, the BitmapMetadata object is frozen. So, you need to clone the BitmapMetadata and then
                // set the padding on it. Lastly, you need to create a "new" frame with the updated metadata.
                BitmapMetadata metadata = original.Frames[0].Metadata.Clone() as BitmapMetadata;
                // Of the metadata handlers that we ship in WIC, padding can only exist in IFD, EXIF, and XMP.
                // Third parties implementing their own metadata handler may wish to support IWICFastMetadataEncoder
                // and hence support padding as well.
                metadata.SetQuery("/app1/ifd/PaddingSchema:Padding", paddingAmount);
                metadata.SetQuery("/app1/ifd/exif/PaddingSchema:Padding", paddingAmount);
                metadata.SetQuery("/xmp/PaddingSchema:Padding", paddingAmount);
                // Since you're already adding metadata now, you can go ahead and add metadata up front.
                metadata.SetQuery("/app1/ifd/{uint=897}", "hello there");
                metadata.SetQuery("/app1/ifd/{uint=898}", "this is a test");
                metadata.Title = "This is a title";
                // Create a new frame identical to the one from the original image, except the metadata will have padding.
                // Essentially we want to keep this as close as possible to:
                //     output.Frames = original.Frames;
                output.Frames.Add(BitmapFrame.Create(original.Frames[0], original.Frames[0].Thumbnail, metadata, original.Frames[0].ColorContexts));
            }
            using (Stream outputFile = File.Open(outputPath, FileMode.Create, FileAccess.ReadWrite))
            {
                output.Save(outputFile);
            }
        }
        // For sanity, let's verify that the original and the output contain image bits that are the same.
        using (Stream originalFile = File.Open(originalPath, FileMode.Open, FileAccess.Read))
        {
            BitmapDecoder original = BitmapDecoder.Create(originalFile, createOptions, BitmapCacheOption.None);
            using (Stream savedFile = File.Open(outputPath, FileMode.Open, FileAccess.Read))
            {
                BitmapDecoder output = BitmapDecoder.Create(savedFile, createOptions, BitmapCacheOption.None);
                Compare(original.Frames[0], output.Frames[0], 0, "foo", Console.Out);
            }
        }
        // Let's copy the file before we use the InPlaceBitmapMetadataWriter so that you can verify the metadata changes.
        File.Copy(outputPath, finalPath, true);
        Console.WriteLine();
        // Now let's use the InPlaceBitmapMetadataWriter.
        using (Stream savedFile = File.Open(outputPath, FileMode.Open, FileAccess.ReadWrite))
        {
            ConsoleColor  originalColor          = Console.ForegroundColor;
            BitmapDecoder output                 = BitmapDecoder.Create(savedFile, BitmapCreateOptions.None, BitmapCacheOption.Default);
            InPlaceBitmapMetadataWriter metadata = output.Frames[0].CreateInPlaceBitmapMetadataWriter();
            // Within the InPlaceBitmapMetadataWriter, you can add, update, or remove metadata.
            //metadata.SetQuery("/app1/ifd/{uint=899}", "this is a test of the InPlaceBitmapMetadataWriter");
            //metadata.RemoveQuery("/app1/ifd/{uint=898}");
            //metadata.SetQuery("/app1/ifd/{uint=897}", "Hello there!!");
            Console.WriteLine("#####################");
            Console.WriteLine(metadata.GetQuery(@"/app13/irb/8bimiptc/iptc/City"));
            Console.WriteLine("#####################");
            metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/Headline", "TEst");
            metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/City", "TEst");
            metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/CountryPrimaryLocationName", "TEst");
            metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/ByLine", "TEst");
            metadata.SetQuery(@"/app13/irb/8bimiptc/iptc/CaptionAbstract", "TEst");
            Console.WriteLine("#####################");
            Console.WriteLine(metadata.GetQuery(@"/app13/irb/8bimiptc/iptc/City"));
            Console.WriteLine("#####################");
            if (metadata.TrySave())
            {
                Console.ForegroundColor = ConsoleColor.Green;
                Console.WriteLine("InPlaceMetadataWriter succeeded!");
            }
            else
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine("InPlaceMetadataWriter failed!");
            }
            Console.ForegroundColor = originalColor;
        }
        FileInfo originalInfo = new FileInfo(originalPath);
        FileInfo outputInfo   = new FileInfo(outputPath);
        FileInfo finalInfo    = new FileInfo(finalPath);

        Console.WriteLine(outputPath);
        Console.WriteLine();
        Console.WriteLine("Original File Size: \t\t\t{0}", originalInfo.Length);
        Console.WriteLine("After Padding File Size: \t\t{0}", outputInfo.Length);
        Console.WriteLine("After InPlaceBitmapWriter File Size: \t{0}", finalInfo.Length);
    }