コード例 #1
0
 public Vr180Jpeg(Bitmap left, Bitmap right, ExifReadWrite exifSegment, long jpegQuality)
 {
     GetLeftEye  = left;
     GetRightEye = right;
     ExifSegment = exifSegment;
     JpegQuality = jpegQuality;
 }
コード例 #2
0
        private static void ProcessFile(string inputFileName, string outputFileName, long jpegQuality = 100)
        {
            LinkedList <Tuple <string, byte[]> > jpegSegments;
            JpegFile jpegFile = new JpegFile();
            Dictionary <string, string> panoDict;

            byte[] extendedXMPURI       = Encoding.UTF8.GetBytes("http://ns.adobe.com/xmp/extension/");
            byte[] zeroByte             = { 0x0 };
            byte[] extendedXMPSignature = null;
            string extendXMP            = "";

            //            string inputJpeg = args[0];
            //            string outputJpeg = args[1];
            ExifReadWrite exif = new ExifReadWrite();


            using (var stream = File.OpenRead(inputFileName))
                jpegSegments = jpegFile.Parse(stream);

            bool xmpFound         = false;
            bool extendedXMPFound = false;

            foreach (var segment in jpegSegments)
            {
                //Console.WriteLine(segment.Item1);

                if (segment.Item1 == "EXIF")
                {
                    exif.ReadExifAPP1(segment.Item2);
                }

                if (xmpFound != true && segment.Item1 == "APP1")
                {
                    string start = Encoding.UTF8.GetString(segment.Item2, 0, 28);
                    if (start == "http://ns.adobe.com/xap/1.0/")
                    {
                        // XMP, extract the GPano if its there.
                        panoDict = jpegFile.ExtractGPano(Encoding.UTF8.GetString(segment.Item2, 29, segment.Item2.Length - 29));
                        string xmpMD5;
                        if (panoDict.TryGetValue("xmpNote:HasExtendedXMP", out xmpMD5))
                        {
                            extendedXMPSignature = extendedXMPURI.Concat(zeroByte).Concat(Encoding.UTF8.GetBytes(xmpMD5)).ToArray();
                            extendedXMPFound     = true;
                        }
                    }
                }

                if (extendedXMPFound == true && segment.Item1 == "APP1" && jpegFile.segmentCompare(extendedXMPSignature, segment.Item2))
                {
                    extendXMP += jpegFile.ProcessExtendedXMPSegemnt(segment.Item2, extendXMP.Length);
                }
            }

            var md5     = System.Security.Cryptography.MD5.Create();
            var md5hash = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(extendXMP));

            var sb = new StringBuilder();

            for (int i = 0; i < md5hash.Length; i++)
            {
                sb.Append(md5hash[i].ToString("x2"));
            }

            if (extendXMP.Length > 0)
            {
                var newJpeg = jpegFile.ProcessExtendedXMPXML(extendXMP);
                if (newJpeg != null)
                {
                    jpegFile.WriteCombineImage(inputFileName, outputFileName, newJpeg, exif, jpegQuality);
                }
            }
        }
コード例 #3
0
        public Vr180Jpeg SplitImage(string orginalJpeg, string format, long newJpegQuailty)
        {
            Bitmap    firstHalf, secondHalf;
            Bitmap    originalImage = new Bitmap(Image.FromFile(orginalJpeg));
            Rectangle rect;

            switch (format)
            {
            case "lr":

                rect      = new Rectangle(0, 0, originalImage.Width / 2, originalImage.Height);
                firstHalf = originalImage.Clone(rect, originalImage.PixelFormat);

                rect       = new Rectangle(originalImage.Width / 2, 0, originalImage.Width / 2, originalImage.Height);
                secondHalf = originalImage.Clone(rect, originalImage.PixelFormat);

                break;

            case "rl":

                rect      = new Rectangle(originalImage.Width / 2, 0, originalImage.Width / 2, originalImage.Height);
                firstHalf = originalImage.Clone(rect, originalImage.PixelFormat);

                rect       = new Rectangle(0, 0, originalImage.Width / 2, originalImage.Height);
                secondHalf = originalImage.Clone(rect, originalImage.PixelFormat);

                break;

            case "tb":

                rect      = new Rectangle(0, 0, originalImage.Width, originalImage.Height / 2);
                firstHalf = originalImage.Clone(rect, originalImage.PixelFormat);

                rect       = new Rectangle(0, originalImage.Height / 2, originalImage.Width, originalImage.Height / 2);
                secondHalf = originalImage.Clone(rect, originalImage.PixelFormat);

                break;

            case "bt":

                rect      = new Rectangle(0, originalImage.Height / 2, originalImage.Width, originalImage.Height / 2);
                firstHalf = originalImage.Clone(rect, originalImage.PixelFormat);

                rect       = new Rectangle(0, 0, originalImage.Width, originalImage.Height / 2);
                secondHalf = originalImage.Clone(rect, originalImage.PixelFormat);

                break;

            default:

                firstHalf  = null;
                secondHalf = null;
                break;
            }

            originalImage.Dispose();

            var exiflib = new ExifReadWrite();

            using (FileStream fs = new FileStream(orginalJpeg, FileMode.Open, FileAccess.Read)) {
                var segments = Parse(fs);
                foreach (var segment in segments)
                {
                    if (segment.Item1 == "EXIF")
                    {
                        exiflib.ReadExifAPP1(segment.Item2);
                    }
                }
            }

            return(new Vr180Jpeg(firstHalf, secondHalf, exiflib, newJpegQuailty));
        }
コード例 #4
0
        public string WriteCombineImage(string inputJpeg, string outputJpeg, byte[] newJpeg, ExifReadWrite exif, long jpegQuality)
        {
            Image    img1 = Image.FromFile(inputJpeg);
            Image    img2 = Image.FromStream(new MemoryStream(newJpeg));
            Bitmap   newBitmap;
            Graphics canvas;
            int      height, width;

            int EXIF_HEIGHT_ID = 0x0100;
            int EXIF_WIDTH_ID  = 0x0101;

            // Draw both images to one bitmap

            if (img1.Width > img1.Height)
            {
                // top bottom
                height = img1.Height + img2.Height;
                width  = Math.Max(img1.Width, img2.Width);

                newBitmap = new Bitmap(width, height);
                canvas    = Graphics.FromImage(newBitmap);
                canvas.Clear(Color.Black);
                canvas.DrawImage(img1, new Point(0, 0));
                canvas.DrawImage(img2, new Point(0, img1.Height));
            }
            else
            {
                width  = img1.Width + img2.Width;
                height = Math.Max(img1.Height, img2.Height);

                newBitmap = new Bitmap(width, height);
                canvas    = Graphics.FromImage(newBitmap);

                canvas.Clear(Color.Black);
                canvas.DrawImage(img1, new Point(0, 0));
                canvas.DrawImage(img2, new Point(img1.Width, 0));
            }

            foreach (PropertyItem property in img1.PropertyItems)
            {
                if (property.Id == EXIF_HEIGHT_ID)
                {
                    byte[] newHeight = BitConverter.GetBytes(height);
                    property.Value = newHeight;
                }
                else if (property.Id == EXIF_WIDTH_ID)
                {
                    byte[] newWidth = BitConverter.GetBytes(width);
                    property.Value = newWidth;
                }

                newBitmap.SetPropertyItem(property);
            }

            // clear up the memory, we only need the bitmap from the combined image for here in.
            canvas.Dispose();
            img1.Dispose();
            img2.Dispose();

            using (MemoryStream jpegms = new MemoryStream())
                using (FileStream jpegOut = new FileStream(outputJpeg, FileMode.OpenOrCreate, FileAccess.Write)) {
                    // write the combined image in a in-memory temporary jpeg as we need to manipulate the metadata before writing to disk.
                    using (EncoderParameters encoderParameters = new EncoderParameters(1))
                        using (EncoderParameter encoderParameter = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, jpegQuality)) {
                            ImageCodecInfo codecInfo = ImageCodecInfo.GetImageDecoders().First(codec => codec.FormatID == ImageFormat.Jpeg.Guid);
                            encoderParameters.Param[0] = encoderParameter;
                            newBitmap.Save(jpegms, codecInfo, encoderParameters);
                        }

                    height = newBitmap.Height;
                    width  = newBitmap.Width;

                    newBitmap.Dispose();
                    jpegms.Flush();
                    jpegms.Position = 0;

                    byte[] jpegTagBuffer    = new byte[2];
                    byte[] jpegLengthBuffer = new byte[2];
                    byte[] networkLength    = new byte[2];

                    jpegms.Read(jpegTagBuffer, 0, 2);
                    jpegOut.Write(jpegTagBuffer, 0, 2);

                    bool writeExifRead = false;

                    while (writeExifRead == false)
                    {
                        jpegms.Read(jpegTagBuffer, 0, 2);

                        if (jpegTagBuffer[0] == 0xFF && (jpegTagBuffer[1] == 0xE1 || jpegTagBuffer[1] == 0xE0))
                        {
                            jpegms.Read(jpegLengthBuffer, 0, 2);
                            if (BitConverter.IsLittleEndian)
                            {
                                networkLength[0] = jpegLengthBuffer[1];
                                networkLength[1] = jpegLengthBuffer[0];
                            }
                            else
                            {
                                networkLength[0] = jpegLengthBuffer[0];
                                networkLength[1] = jpegLengthBuffer[1];
                            }

                            ushort length  = BitConverter.ToUInt16(networkLength, 0);
                            byte[] segment = new byte[length - 2];

                            jpegms.Read(segment, 0, length - 2);

                            // skip an exif if we are copying the originals
                            if (segment[0] == 'E' &&
                                segment[1] == 'x' &&
                                segment[2] == 'i' &&
                                segment[3] == 'f' &&
                                segment[4] == 0x00 && exif.Properties.Count > 0)
                            {
                                Console.WriteLine("New Jpeg has an existing Exif, replacing.");
                                continue;
                            }

                            // write it out
                            jpegOut.Write(jpegTagBuffer, 0, 2);
                            jpegOut.Write(jpegLengthBuffer, 0, 2);
                            jpegOut.Write(segment, 0, length - 2);
                        }
                        else
                        {
                            writeExifRead = true;
                        }
                    }

                    // add in an Exif if we've got properties...
                    if (exif.Properties.Count > 0)
                    {
                        // replace height and width

                        foreach (var prop in exif.Properties)
                        {
                            // Console.WriteLine(prop.Name);
                            if (prop.Name == "PixelXDimension")
                            {
                                prop.Value = (uint)width;
                            }

                            if (prop.Name == "PixelYDimension")
                            {
                                prop.Value = (uint)height;
                            }
                        }

                        byte[] exifBuffer    = exif.WriteExifApp1(true);
                        byte[] exifTagBuffer = { 0xFF, 0xE1 };

                        ushort exifLength = (ushort)(exifBuffer.Length + 2);

                        networkLength = BitConverter.GetBytes(exifLength);
                        if (BitConverter.IsLittleEndian)
                        {
                            Array.Reverse(networkLength);
                        }

                        jpegOut.Write(exifTagBuffer, 0, 2);
                        jpegOut.Write(networkLength, 0, 2);
                        jpegOut.Write(exifBuffer, 0, exifBuffer.Length);
                    }

                    // finish of writing the jpeg, starting with the last tag read.
                    jpegOut.Write(jpegTagBuffer, 0, 2);
                    jpegms.CopyTo(jpegOut);

                    jpegms.Flush();
                    jpegOut.Flush();
                }

            return("OK");
        }