Пример #1
0
        /// <summary>
        /// fileName can be in form "C:\\aaa\aaa.zip|bbb\bbb.jpg"
        /// imageName will be generated if name=null is passed (in the form of "bbb.jpg")
        /// </summary>
        /// <param name="zip"></param>
        /// <param name="zipEntry"></param>
        /// <param name="fileName"></param>
        /// <param name="imageName"></param>
        /// <returns></returns>
        public static PhotoDescr FromFileOrZipEntry(ZipFile zip, ZipEntry zipEntry, string fileName, string name)
        {
            PhotoDescr ret = new PhotoDescr();

            Stream stream     = null;
            bool   doCloseZip = false;

            ret.imageName = name;

            if (zip == null)
            {
                int pos = fileName.IndexOf("|");
                if (pos >= 0)
                {
                    // this is a .zip or .gpz file
                    string zipFileName = fileName.Substring(0, pos);

                    if (!File.Exists(zipFileName))
                    {
                        LibSys.StatusBar.Error("Failed to open Zip");
                        throw new InvalidOperationException("'" + zipFileName + "' not found or not a valid zip file");
                    }

                    zip = new ZipFile(zipFileName);

                    doCloseZip = true;
                    string photoFileName = fileName.Substring(pos + 1);

                    zipEntry = zip.GetEntry(photoFileName);
                    if (zipEntry == null)
                    {
                        zip.Close();
                        throw new InvalidOperationException("'" + photoFileName + "' is not found inside " + zipFileName);
                    }
                }
                else
                {
                    // plain file
                    ret.imageSource = fileName;
                    if (ret.imageName == null)
                    {
                        // generate image name based on file name:
                        ret.imageName = imageNameFromFileName(Path.GetFileName(fileName));
                    }
                }
            }

            if (zip != null)
            {
                ret.imageSource = zip.Name + "|" + zipEntry.Name;
                if (ret.imageName == null)
                {
                    // generate image name based on file name:
                    int    pos = zipEntry.Name.LastIndexOf("\\");
                    string imageFileName;
                    if (pos >= 0)
                    {
                        imageFileName = zipEntry.Name.Substring(pos + 1);
                    }
                    else
                    {
                        imageFileName = zipEntry.Name;
                    }
                    ret.imageName = imageNameFromFileName(imageFileName);
                }

                stream = zip.GetInputStream(zipEntry);
            }

            // Create an Image object from the specified file.
            Image img = null;

            try
            {
                img        = (zip == null) ? Image.FromFile(fileName, true) : new Bitmap(stream);
                ret.Width  = img.Width;
                ret.Height = img.Height;
                ret.image  = img;
            }
            // An invalid image will throw an OutOfMemoryException
            catch (OutOfMemoryException)
            {
                if (doCloseZip)
                {
                    zip.Close();
                }
                throw new InvalidOperationException("'" + fileName + "' is not a valid image file.");
            }

            if (doCloseZip)
            {
                zip.Close();
            }

            try
            {
                //	<tagMetadata id="36867" category="EXIF">
                //		<name>DTOrig</name>
                //		<description>Date and time when the original image data was generated. For a DSC, the date and time when the picture was taken. The format is YYYY:MM:DD HH:MM:SS with time shown in 24-hour format and the date and time separated by one blank character (0x2000). The character string length is 20 bytes including the NULL terminator. When the field is empty, it is treated as unknown.</description>
                //	</tagMetadata>
                //	<tagMetadata id="36868" category="EXIF">
                //		<name>DTDigitized</name>
                //		<description>Date and time when the image was stored as digital data. If, for example, an image was captured by DSC and at the same time the file was recorded, then DateTimeOriginal and DateTimeDigitized will have the same contents. The format is YYYY:MM:DD HH:MM:SS with time shown in 24-hour format and the date and time separated by one blank character (0x2000). The character string length is 20 bytes including the NULL terminator. When the field is empty, it is treated as unknown.</description>
                //	</tagMetadata>

                PropertyItem prop = img.GetPropertyItem(36867);
                switch (prop.Type)
                {
                case 2:
                    string   sTime = Project.ByteArrayToStr(prop.Value);                                        // "2003:08:05 20:12:23"
                    string[] split = sTime.Split(new Char[] { ' ' });
                    sTime      = split[0].Replace(":", "/") + " " + split[1];
                    ret.DTOrig = Convert.ToDateTime(sTime);                                             // local, how time in the camera is set
                    break;
                }
            }
            catch (Exception)
            {
            }

            try
            {
                //	<tagMetadata id="1" category="GPS">
                //		<name>GPSLatitudeRef</name>
                //		<description>Indicates whether the latitude is north or south latitude.
                //		The ASCII value 'N' indicates north latitude, and 'S' is south latitude.</description>
                //		<valueOptions>
                //			<option key="N" keyType="CHAR" value="North latitude" />
                //			<option key="S" keyType="CHAR" value="South latitude" />
                //			<optionOtherwise value="reserved" />
                //		</valueOptions>
                //	</tagMetadata>
                //	<tagMetadata id="2" category="GPS">
                //		<name>GPSLatitude</name>
                //		<description>Indicates the latitude. The latitude is expressed as three
                //		RATIONAL values giving the degrees, minutes, and seconds, respectively.
                //		When degrees, minutes and seconds are expressed, the format is dd/1,mm/1,ss/1.
                //		When degrees and minutes are used and, for example, fractions of minutes are
                //		given up to two decimal places, the format is dd/1,mmmm/100,0/1.</description>
                //	</tagMetadata>
                //	<tagMetadata id="3" category="GPS">
                //		<name>GPSLongitudeRef</name>
                //		<description>Indicates whether the longitude is east or west longitude.
                //		The ASCII value 'E' indicates east longitude, and 'W' is west longitude.</description>
                //		<valueOptions>
                //			<option key="E" keyType="CHAR" value="East longitude" />
                //			<option key="W" keyType="CHAR" value="West longitude" />
                //			<optionOtherwise value="reserved" />
                //		</valueOptions>
                //	</tagMetadata>
                //	<tagMetadata id="4" category="GPS">
                //		<name>GPSLongitude</name>
                //		<description>Indicates the longitude. The longitude is expressed as three
                //		RATIONAL values giving the degrees, minutes, and seconds, respectively.
                //		When degrees, minutes and seconds are expressed, the format is ddd/1,mm/1,ss/1.
                //		When degrees and minutes are used and, for example, fractions of minutes are
                //		given up to two decimal places, the format is ddd/1,mmmm/100,0/1.</description>
                //	</tagMetadata>

                string sLatRef = null;
                double lat     = 0.0d;
                string sLngRef = null;
                double lng     = 0.0d;

                PropertyItem prop = img.GetPropertyItem(1);
                switch (prop.Type)
                {
                case 2:
                    sLatRef = Project.ByteArrayToStr(prop.Value);                                       // "N" or "S"
                    break;
                }

                prop = img.GetPropertyItem(2);
                switch (prop.Type)
                {
                case 5:
                    lat = ParseRationalCoord(prop);                                     // "51.0 56.0 33.123"
                    break;
                }

                prop = img.GetPropertyItem(3);
                switch (prop.Type)
                {
                case 2:
                    sLngRef = Project.ByteArrayToStr(prop.Value);                                       // "W" or "E"
                    break;
                }

                prop = img.GetPropertyItem(4);
                switch (prop.Type)
                {
                case 5:
                    lng = ParseRationalCoord(prop);                                     // "4.0 22.0 33.123"
                    break;
                }

                if (sLatRef != null && sLngRef != null)
                {
                    bool isWest  = sLngRef.ToLower().StartsWith("w");
                    bool isSouth = sLatRef.ToLower().StartsWith("s");
                    if (isSouth)
                    {
                        lat = -lat;
                    }
                    if (isWest)
                    {
                        lng = -lng;
                    }
                    ret.Latitude       = lat;
                    ret.Longitude      = lng;
                    ret.hasCoordinates = true;
                }
            }
            catch (Exception)
            {
            }

            try
            {
                //	<tagMetadata id="274" category="">
                //		<name>Orientation</name>
                //		<description>Image orientation viewed in terms of rows and columns.</description>
                //		<valueOptions>
                //			<option key="1" value="The 0th row is at the visual top of the image, and the 0th column is the visual left-hand side." />
                //			<option key="2" value="The 0th row is at the visual top of the image, and the 0th column is the visual right-hand side." />
                //			<option key="3" value="The 0th row is at the visual bottom of the image, and the 0th column is the visual right-hand side." />
                //			<option key="4" value="The 0th row is at the visual bottom of the image, and the 0th column is the visual left-hand side." />
                //			<option key="5" value="The 0th row is the visual left-hand side of of the image, and the 0th column is the visual top." />
                //			<option key="6" value="The 0th row is the visual right-hand side of of the image, and the 0th column is the visual top." />
                //			<option key="7" value="The 0th row is the visual right-hand side of of the image, and the 0th column is the visual bottom." />
                //			<option key="8" value="The 0th row is the visual left-hand side of of the image, and the 0th column is the visual bottom." />
                //			<optionOtherwise value="reserved" />
                //		</valueOptions>
                //	</tagMetadata>
                PropertyItem prop = img.GetPropertyItem(274);
                switch (prop.Type)
                {
                case 3:
                    ret.Orientation = (int)prop.Value[0];                                       // 6 and 8 are known to appear here
                    break;
                }
            }
            catch (Exception)
            {
            }

            return(ret);
        }