예제 #1
0
    /// <summary>
    ///     Initializes a new instance of the <see cref="JPEGFile" /> class from the
    ///     specified data stream.
    /// </summary>
    /// <param name="stream">A <see cref="Sytem.IO.Stream" /> that contains image data.</param>
    /// <param name="encoding">The encoding to be used for text metadata when the source encoding is unknown.</param>
    protected internal TIFFFile(Stream stream, Encoding encoding)
    {
        Format   = ImageFileFormat.TIFF;
        IFDs     = new List <ImageFileDirectory>();
        Encoding = encoding;

        // Read the entire stream
        var data = Utility.GetStreamBytes(stream);

        // Read the TIFF header
        TIFFHeader = TIFFHeader.FromBytes(data, 0);
        var nextIFDOffset = TIFFHeader.IFDOffset;

        if (nextIFDOffset == 0)
        {
            throw new NotValidTIFFileException("The first IFD offset is zero.");
        }

        // Read IFDs in order
        while (nextIFDOffset != 0)
        {
            var ifd = ImageFileDirectory.FromBytes(data, nextIFDOffset, TIFFHeader.ByteOrder);
            nextIFDOffset = ifd.NextIFDOffset;
            IFDs.Add(ifd);
        }

        // Process IFDs
        // TODO: Add support for multiple frames
        foreach (ImageFileDirectoryEntry field in IFDs[0].Fields)
        {
            Properties.Add(ExifPropertyFactory.Get(field.Tag, field.Type, field.Count, field.Data, BitConverterEx.SystemByteOrder, IFD.Zeroth, Encoding));
        }
    }
예제 #2
0
        private void SaveImageToCameraRoll(Stream stream, MemoryStream thumbStream)
        {
            string   fileName = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_fff") + "#" + m_sequenceGuid.ToString();
            ExifFile exif     = ExifFile.ReadStream(stream);
            string   metadata = GetMetadata(fileName);

            byte[] data        = Encoding.UTF8.GetBytes(metadata);
            uint   length      = (uint)data.Length;
            ushort type        = 2;
            var    imgDescProp = ExifPropertyFactory.Get(0x010e, type, length, data, BitConverterEx.ByteOrder.BigEndian, IFD.Zeroth);

            exif.Properties.Add(ExifTag.ImageDescription, imgDescProp);

            using (var ml = new MediaLibrary())
            {
                exif.SaveToCameraRoll("mapi_" + fileName + ".jpg", ml);
                using (var memstream = new MemoryStream())
                {
                    WriteableBitmap bmp = new WriteableBitmap(100, 75);
                    bmp = bmp.FromStream(thumbStream);
                    WriteableBitmap tBmp = bmp.Resize(100, 75, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
                    tBmp.SaveJpeg(memstream, 100, 75, 0, 90);
                    memstream.Seek(0, SeekOrigin.Begin);
                    ml.SavePictureToCameraRoll("mapi_thumb_" + fileName + ".jpg", memstream);
                }
            }

            stream.Close();
            thumbStream.Close();
            stream.Dispose();
            thumbStream.Dispose();
        }
예제 #3
0
        private void SaveImageToIsoStore(Stream stream, MemoryStream thumbStream)
        {
            string   fileName = DateTime.Now.ToString("yyyy_MM_dd_HH_mm_ss_fff") + "#" + m_sequenceGuid.ToString();
            ExifFile exif     = ExifFile.ReadStream(stream);
            string   metadata = GetMetadata(fileName);

            byte[] data        = Encoding.UTF8.GetBytes(metadata);
            uint   length      = (uint)data.Length;
            ushort type        = 2;
            var    imgDescProp = ExifPropertyFactory.Get(0x010e, type, length, data, BitConverterEx.ByteOrder.BigEndian, IFD.Zeroth);

            exif.Properties.Add(ExifTag.ImageDescription, imgDescProp);
            using (IsolatedStorageFile isStore = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!isStore.DirectoryExists("shared"))
                {
                    isStore.CreateDirectory("shared");
                }

                if (!isStore.DirectoryExists("shared\\transfers"))
                {
                    isStore.CreateDirectory("shared\\transfers");
                }
                using (IsolatedStorageFileStream targetStream = isStore.OpenFile(@"shared\\transfers\" + fileName + ".jpg", FileMode.Create, FileAccess.Write))
                {
                    exif.SaveStream(targetStream);
                }


                using (IsolatedStorageFileStream thumbtargetStream = isStore.OpenFile(@"shared\\transfers\thumb_" + fileName + ".jpg", FileMode.Create, FileAccess.Write))
                {
                    WriteableBitmap bmp = new WriteableBitmap(100, 75);
                    bmp = bmp.FromStream(thumbStream);
                    WriteableBitmap tBmp = bmp.Resize(100, 75, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
                    tBmp.SaveJpeg(thumbtargetStream, 100, 75, 0, 90);
                }

                stream.Close();
                thumbStream.Close();
                stream.Dispose();
                thumbStream.Dispose();
            }
        }
예제 #4
0
파일: ExifFile.cs 프로젝트: Sinsyne/Global
        /// <summary>
        /// 读取包含的Exif元数据APP1部分
        /// </summary>
        private void ReadAPP1()
        {
            // Find the APP1 section containing Exif metadata
            app1 = file.Sections.Find(a => (a.Marker == JPEGMarker.APP1) &&
                                      (Encoding.ASCII.GetString(a.Header, 0, 6) == "Exif\0\0"));

            // If there is no APP1 section, add a new one after the last APP0 section (if any).
            if (app1 == null)
            {
                int insertionIndex = file.Sections.FindLastIndex(a => a.Marker == JPEGMarker.APP0);
                if (insertionIndex == -1)
                {
                    insertionIndex = 0;
                }
                insertionIndex++;
                ByteOrder = BitConverterEx.ByteOrder.BigEndian;
                app1      = new JPEGSection(JPEGMarker.APP1);
                file.Sections.Insert(insertionIndex, app1);
                return;
            }

            byte[] header = app1.Header;
            SortedList <int, IFD> ifdqueue = new SortedList <int, IFD>();

            makerNoteOffset = 0;

            // TIFF header
            int tiffoffset = 6;

            if (header[tiffoffset] == 0x49)
            {
                ByteOrder = BitConverterEx.ByteOrder.LittleEndian;
            }
            else
            {
                ByteOrder = BitConverterEx.ByteOrder.BigEndian;
            }
            BitConverterEx conv = new BitConverterEx(ByteOrder, BitConverterEx.ByteOrder.System);

            // Offset to 0th IFD
            int ifd0offset = (int)conv.ToUInt32(header, tiffoffset + 4);

            ifdqueue.Add(ifd0offset, IFD.Zeroth);

            int thumboffset = -1;
            int thumblength = 0;
            int thumbtype   = -1;

            // Read IFDs
            while (ifdqueue.Count != 0)
            {
                int ifdoffset  = tiffoffset + ifdqueue.Keys[0];
                IFD currentifd = ifdqueue.Values[0];
                ifdqueue.RemoveAt(0);

                // Field count
                ushort fieldcount = conv.ToUInt16(header, ifdoffset);
                for (short i = 0; i < fieldcount; i++)
                {
                    // Read field info
                    int    fieldoffset = ifdoffset + 2 + 12 * i;
                    ushort tag         = conv.ToUInt16(header, fieldoffset);
                    ushort type        = conv.ToUInt16(header, fieldoffset + 2);
                    uint   count       = conv.ToUInt32(header, fieldoffset + 4);
                    byte[] value       = new byte[4];
                    Array.Copy(header, fieldoffset + 8, value, 0, 4);

                    // Fields containing offsets to other IFDs
                    if (currentifd == IFD.Zeroth && tag == 0x8769)
                    {
                        int exififdpointer = (int)conv.ToUInt32(value, 0);
                        ifdqueue.Add(exififdpointer, IFD.EXIF);
                    }
                    else if (currentifd == IFD.Zeroth && tag == 0x8825)
                    {
                        int gpsifdpointer = (int)conv.ToUInt32(value, 0);
                        ifdqueue.Add(gpsifdpointer, IFD.GPS);
                    }
                    else if (currentifd == IFD.EXIF && tag == 0xa005)
                    {
                        int interopifdpointer = (int)conv.ToUInt32(value, 0);
                        ifdqueue.Add(interopifdpointer, IFD.Interop);
                    }

                    // Save the offset to maker note data
                    if (currentifd == IFD.EXIF && tag == 37500)
                    {
                        makerNoteOffset = conv.ToUInt32(value, 0);
                    }

                    // Calculate the bytes we need to read
                    uint baselength = 0;
                    if (type == 1 || type == 2 || type == 7)
                    {
                        baselength = 1;
                    }
                    else if (type == 3)
                    {
                        baselength = 2;
                    }
                    else if (type == 4 || type == 9)
                    {
                        baselength = 4;
                    }
                    else if (type == 5 || type == 10)
                    {
                        baselength = 8;
                    }
                    uint totallength = count * baselength;

                    // If field value does not fit in 4 bytes
                    // the value field is an offset to the actual
                    // field value
                    int fieldposition = 0;
                    if (totallength > 4)
                    {
                        fieldposition = tiffoffset + (int)conv.ToUInt32(value, 0);
                        value         = new byte[totallength];
                        Array.Copy(header, fieldposition, value, 0, totallength);
                    }

                    // Compressed thumbnail data
                    if (currentifd == IFD.First && tag == 0x201)
                    {
                        thumbtype   = 0;
                        thumboffset = (int)conv.ToUInt32(value, 0);
                    }
                    else if (currentifd == IFD.First && tag == 0x202)
                    {
                        thumblength = (int)conv.ToUInt32(value, 0);
                    }

                    // Uncompressed thumbnail data
                    if (currentifd == IFD.First && tag == 0x111)
                    {
                        thumbtype = 1;
                        // Offset to first strip
                        if (type == 3)
                        {
                            thumboffset = (int)conv.ToUInt16(value, 0);
                        }
                        else
                        {
                            thumboffset = (int)conv.ToUInt32(value, 0);
                        }
                    }
                    else if (currentifd == IFD.First && tag == 0x117)
                    {
                        thumblength = 0;
                        for (int j = 0; j < count; j++)
                        {
                            if (type == 3)
                            {
                                thumblength += (int)conv.ToUInt16(value, 0);
                            }
                            else
                            {
                                thumblength += (int)conv.ToUInt32(value, 0);
                            }
                        }
                    }

                    // Create the exif property from the interop data
                    ExifProperty prop = ExifPropertyFactory.Get(tag, type, count, value, ByteOrder, currentifd);
                    Properties.Add(prop.Tag, prop);
                }

                // 1st IFD pointer
                int firstifdpointer = (int)conv.ToUInt32(header, ifdoffset + 2 + 12 * fieldcount);
                if (firstifdpointer != 0)
                {
                    ifdqueue.Add(firstifdpointer, IFD.First);
                }
                // Read thumbnail
                if (thumboffset != -1 && thumblength != 0 && Thumbnail == null)
                {
                    if (thumbtype == 0)
                    {
                        using (MemoryStream ts = new MemoryStream(header, tiffoffset + thumboffset, thumblength))
                        {
                            Thumbnail = new JPEGFile(ts);
                        }
                    }
                }
            }
        }
예제 #5
0
    /// <summary>
    ///     Reads the APP1 section containing Exif metadata.
    /// </summary>
    private void ReadExifAPP1()
    {
        // Find the APP1 section containing Exif metadata
        _exifApp1 = Sections.Find(a => a.Marker == JPEGMarker.APP1 &&
                                  a.Header.Length >= 6 &&
                                  Encoding.ASCII.GetString(a.Header, 0, 6) == "Exif\0\0");

        // If there is no APP1 section, add a new one after the last APP0 section (if any).
        if (_exifApp1 == null)
        {
            var insertionIndex = Sections.FindLastIndex(a => a.Marker == JPEGMarker.APP0);
            if (insertionIndex == -1)
            {
                insertionIndex = 0;
            }

            insertionIndex++;
            _exifApp1 = new JPEGSection(JPEGMarker.APP1);
            Sections.Insert(insertionIndex, _exifApp1);
            if (BitConverterEx.SystemByteOrder == BitConverterEx.ByteOrder.LittleEndian)
            {
                ByteOrder = BitConverterEx.ByteOrder.LittleEndian;
            }
            else
            {
                ByteOrder = BitConverterEx.ByteOrder.BigEndian;
            }

            return;
        }

        var header   = _exifApp1.Header;
        var ifdqueue = new SortedList <int, IFD>();

        _makerNoteOffset = 0;

        // TIFF header
        var tiffoffset = 6;

        if (header[tiffoffset] == 0x49 && header[tiffoffset + 1] == 0x49)
        {
            ByteOrder = BitConverterEx.ByteOrder.LittleEndian;
        }
        else if (header[tiffoffset] == 0x4D && header[tiffoffset + 1] == 0x4D)
        {
            ByteOrder = BitConverterEx.ByteOrder.BigEndian;
        }
        else
        {
            throw new NotValidExifFileException();
        }

        // TIFF header may have a different byte order
        BitConverterEx.ByteOrder tiffByteOrder = ByteOrder;
        if (BitConverterEx.LittleEndian.ToUInt16(header, tiffoffset + 2) == 42)
        {
            tiffByteOrder = BitConverterEx.ByteOrder.LittleEndian;
        }
        else if (BitConverterEx.BigEndian.ToUInt16(header, tiffoffset + 2) == 42)
        {
            tiffByteOrder = BitConverterEx.ByteOrder.BigEndian;
        }
        else
        {
            throw new NotValidExifFileException();
        }

        // Offset to 0th IFD
        var ifd0offset = (int)BitConverterEx.ToUInt32(header, tiffoffset + 4, tiffByteOrder, BitConverterEx.SystemByteOrder);

        ifdqueue.Add(ifd0offset, IFD.Zeroth);

        var conv        = new BitConverterEx(ByteOrder, BitConverterEx.SystemByteOrder);
        var thumboffset = -1;
        var thumblength = 0;
        var thumbtype   = -1;

        // Read IFDs
        while (ifdqueue.Count != 0)
        {
            var ifdoffset  = tiffoffset + ifdqueue.Keys[0];
            IFD currentifd = ifdqueue.Values[0];
            ifdqueue.RemoveAt(0);

            // Field count
            var fieldcount = conv.ToUInt16(header, ifdoffset);
            for (short i = 0; i < fieldcount; i++)
            {
                // Read field info
                var fieldoffset = ifdoffset + 2 + (12 * i);
                var tag         = conv.ToUInt16(header, fieldoffset);
                var type        = conv.ToUInt16(header, fieldoffset + 2);
                var count       = conv.ToUInt32(header, fieldoffset + 4);
                var value       = new byte[4];
                Array.Copy(header, fieldoffset + 8, value, 0, 4);

                // Fields containing offsets to other IFDs
                if (currentifd == IFD.Zeroth && tag == 0x8769)
                {
                    var exififdpointer = (int)conv.ToUInt32(value, 0);
                    ifdqueue.Add(exififdpointer, IFD.EXIF);
                }
                else if (currentifd == IFD.Zeroth && tag == 0x8825)
                {
                    var gpsifdpointer = (int)conv.ToUInt32(value, 0);
                    ifdqueue.Add(gpsifdpointer, IFD.GPS);
                }
                else if (currentifd == IFD.EXIF && tag == 0xa005)
                {
                    var interopifdpointer = (int)conv.ToUInt32(value, 0);
                    ifdqueue.Add(interopifdpointer, IFD.Interop);
                }

                // Save the offset to maker note data
                if (currentifd == IFD.EXIF && tag == 37500)
                {
                    _makerNoteOffset = conv.ToUInt32(value, 0);
                }

                // Calculate the bytes we need to read
                uint baselength = 0;
                if (type == 1 || type == 2 || type == 7)
                {
                    baselength = 1;
                }
                else if (type == 3)
                {
                    baselength = 2;
                }
                else if (type == 4 || type == 9)
                {
                    baselength = 4;
                }
                else if (type == 5 || type == 10)
                {
                    baselength = 8;
                }

                var totallength = count * baselength;

                // If field value does not fit in 4 bytes
                // the value field is an offset to the actual
                // field value
                var fieldposition = 0;
                if (totallength > 4)
                {
                    fieldposition = tiffoffset + (int)conv.ToUInt32(value, 0);
                    value         = new byte[totallength];
                    Array.Copy(header, fieldposition, value, 0, totallength);
                }

                // Compressed thumbnail data
                if (currentifd == IFD.First && tag == 0x201)
                {
                    thumbtype   = 0;
                    thumboffset = (int)conv.ToUInt32(value, 0);
                }
                else if (currentifd == IFD.First && tag == 0x202)
                {
                    thumblength = (int)conv.ToUInt32(value, 0);
                }

                // Uncompressed thumbnail data
                if (currentifd == IFD.First && tag == 0x111)
                {
                    thumbtype = 1;

                    // Offset to first strip
                    if (type == 3)
                    {
                        thumboffset = conv.ToUInt16(value, 0);
                    }
                    else
                    {
                        thumboffset = (int)conv.ToUInt32(value, 0);
                    }
                }
                else if (currentifd == IFD.First && tag == 0x117)
                {
                    thumblength = 0;
                    for (var j = 0; j < count; j++)
                    {
                        if (type == 3)
                        {
                            thumblength += conv.ToUInt16(value, 0);
                        }
                        else
                        {
                            thumblength += (int)conv.ToUInt32(value, 0);
                        }
                    }
                }

                // Create the exif property from the interop data
                ExifProperty prop = ExifPropertyFactory.Get(tag, type, count, value, ByteOrder, currentifd, Encoding);
                Properties.Add(prop);
            }

            // 1st IFD pointer
            var firstifdpointer = (int)conv.ToUInt32(header, ifdoffset + 2 + (12 * fieldcount));
            if (firstifdpointer != 0)
            {
                ifdqueue.Add(firstifdpointer, IFD.First);
            }

            // Read thumbnail
            if (thumboffset != -1 && thumblength != 0 && Thumbnail == null)
            {
                if (thumbtype == 0)
                {
                    using (var ts = new MemoryStream(header, tiffoffset + thumboffset, thumblength))
                    {
                        Thumbnail = FromStream(ts);
                    }
                }
            }
        }
    }
예제 #6
0
        private void rotateBtn_Click(object sender, RoutedEventArgs e)
        {
            previewImage.Source = null;
            if (m_selectedFile != null)
            {
                Dictionary <ExifTag, ExifProperty> exifProperties = new Dictionary <ExifTag, ExifProperty>();
                using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    WriteableBitmap bmp      = new WriteableBitmap(0, 0);
                    string          exifData = null;
                    using (var fileStream = storage.OpenFile(m_selectedFile.Path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        ExifFile exif = ExifFile.ReadStream(fileStream);
                        var      data = exif.Properties[ExifTag.ImageDescription];
                        exifData = (string)data.Value;
                        fileStream.Close();
                    }

                    using (var fileStream = storage.OpenFile(m_selectedFile.Path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        bmp = bmp.FromStream(fileStream);
                        bmp = bmp.Rotate(90);
                        fileStream.Close();
                    }

                    lock (readLock)
                    {
                        using (IsolatedStorageFileStream stream = storage.CreateFile(@"shared\\transfers\" + m_selectedFile.Name))
                        {
                            bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 98);
                            stream.Close();
                        }
                    }


                    ExifFile exifRotated;
                    using (var fileStream = storage.OpenFile(m_selectedFile.Path, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        exifRotated = ExifFile.ReadStream(fileStream);
                        fileStream.Close();
                        byte[] data        = Encoding.UTF8.GetBytes(exifData);
                        uint   length      = (uint)data.Length;
                        ushort type        = 2;
                        var    imgDescProp = ExifPropertyFactory.Get(0x010e, type, length, data, BitConverterEx.ByteOrder.BigEndian, IFD.Zeroth);
                        exifRotated.Properties.Add(ExifTag.ImageDescription, imgDescProp);
                    }

                    lock (readLock)
                    {
                        using (IsolatedStorageFileStream targetStream = storage.OpenFile(m_selectedFile.Path, FileMode.Create, FileAccess.Write, FileShare.None))
                        {
                            exifRotated.SaveStream(targetStream);
                            targetStream.Close();
                        }
                    }

                    previewImage.Source = bmp;
                }
            }

            if (m_selectedThumbFile != null)
            {
                using (IsolatedStorageFile storage = IsolatedStorageFile.GetUserStoreForApplication())
                {
                    var  bmp   = new WriteableBitmap(0, 0);
                    bool exist = storage.FileExists(m_selectedThumbFile.Path);
                    if (exist)
                    {
                        using (var fileStream = storage.OpenFile(m_selectedThumbFile.Path, FileMode.Open, FileAccess.Read, FileShare.None))
                        {
                            bmp = bmp.FromStream(fileStream);
                            bmp = bmp.Rotate(90);
                            fileStream.Close();
                        }

                        lock (readLock)
                        {
                            using (IsolatedStorageFileStream stream = storage.CreateFile(@"shared\\transfers\" + m_selectedThumbFile.Name))
                            {
                                bmp.SaveJpeg(stream, bmp.PixelWidth, bmp.PixelHeight, 0, 98);
                                stream.Close();
                            }
                        }

                        viewModel.PhotoList[m_selectionIndex - 1].ImageSource = new BitmapImage(new Uri(m_selectedThumbFile.Path))
                        {
                            CreateOptions = BitmapCreateOptions.IgnoreImageCache
                        };
                    }
                }
            }
        }