Проблема C# привязка тегов метаданных к списку для 0x5013 и 0x5014.
Привет,
Я хочу отобразить определенные метаданные в моем списке для выбранного изображения в моем средстве просмотра изображений, которого нет в этой библиотеке Asim Goheer, которую я использую. https://www.codeproject.com/Articles/11305/EXIFextractor-library-to-extract-EXIF-information?msg=5528243#xx5528243xx
ПРОБЛЕМА:
К сожалению, у меня возникли проблемы с реализацией новых тегов, которых не было в EXIFextractor.Метод BuildDB ().
Системы.Исключение NullReferenceException. Системы.Исключение NullReferenceException: Объекта
ссылка не установлена на экземпляр объекта.' bmp был равен нулю.
Это происходит после попытки я установил тег для
er2.setTag(0x5013,"Thumbnail Width");
в моей форме.
На самом деле это происходит с любым тегом. Я пытаюсь реализовать код как для 0x5014,"Высота миниатюры", так и для 0x5013,"ширина миниатюры".
Вот мой код для моей формы Windows, только этот код мой. Классы ниже, где написано Асим Гохир, спасибо.
Форма 1.
using System; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.Linq; using System.Text; using System.Windows.Forms; using System.Web.UI; namespace PictureViewer { public partial class Form1 : Form { string _big_fileName; int _counter = 0; int _imageIndex; #region Initializers public Form1() { InitializeComponent(); } //Displays larger instance of selected image in picture box. private void lstImages_SelectedIndexChanged(object sender, EventArgs e) { //FOR i is less than the first image. for (int i = 0; i < lstImages.SelectedItems.Count; i++) { //GET filename from listview and store in index. _big_fileName = lstImages.SelectedItems[i].Text; //Create larger instance of image. pictureBox1.Image = Image.FromFile(_big_fileName); //Fill panel to the width and height of picture box. panel1.AutoScrollMinSize = new Size(pictureBox1.Image.Width, pictureBox1.Image.Height); _imageIndex = lstImages.SelectedIndices[0]; loadImageMetaData(); } } #endregion Initializers #region File Menu Events private void mnuOpen_Click(object sender, EventArgs e) { loadImageList(); _imageIndex = 0; } #region Methods private void loadImageList() { imageList1.Images.Clear(); lstImages.Clear(); oFD1.InitialDirectory = "C:\\"; oFD1.Title = "Open an Image File"; oFD1.Filter = "JPEGS|*.jpg|GIFS|*.gif|PNGS|*.png|BMPS|*.bmp"; //Open Dialog Box. var oldResults = oFD1.ShowDialog(); if (oldResults == DialogResult.Cancel) { return; } try { //GET amount of filenames. int num_of_files = oFD1.FileNames.Length; //Store filenames in string array. string[] arryFilePaths = new string[num_of_files]; //FOREACH filename in the file. foreach (string single_file in oFD1.FileNames) { //ACCESS array using _counter to find file. arryFilePaths[_counter] = single_file; //CREATE image in memory and add image to image list. imageList1.Images.Add(Image.FromFile(single_file)); _counter++; } //BIND image list to listview. lstImages.LargeImageList = imageList1; for (int i = 0; i < _counter; i++) { //DISPLAY filename and image from image index param. lstImages.Items.Add(arryFilePaths[i], i); } } catch (Exception ex) { MessageBox.Show("Error " + ex.Message); } } private void loadImageMetaData() { lstImageMetaData.Items.Clear(); Encoding ascii = Encoding.ASCII; EXIF.EXIFextractor er2 = new EXIF.EXIFextractor(_big_fileName, "",""); foreach (Pair s in er2) { lstImageMetaData.Items.Add(s.First + " : " + s.Second); } lstImageMetaData.SelectedIndex = lstImageMetaData.Items.Count - 1; er2.setTag(0x5013,"Thumbnail Width"); } #endregion Methods } }
Ошибка заключается в этом методе
public void setTag(int id, int len, short type, byte [] data) { PropertyItem p = CreatePropertyItem(type,id,len,data); this.bmp.SetPropertyItem( p ); buildDB(this.bmp.PropertyItems); }На этой самой линии.
this.bmp.SetPropertyItem(p);
Вот весь код для EXIFextractor.
using System; using System.Text; using System.Collections; using System.Drawing.Imaging; using System.Reflection; using System.IO; using System.Web.UI; namespace EXIF { /// <summary> /// EXIFextractor Class /// /// </summary> public class EXIFextractor : IEnumerable { /// <summary> /// Get the individual property value by supplying property name /// These are the valid property names : /// /// "Exif IFD" /// "Gps IFD" /// "New Subfile Type" /// "Subfile Type" /// "Image Width" /// "Image Height" /// "Bits Per Sample" /// "Compression" /// "Photometric Interp" /// "Thresh Holding" /// "Cell Width" /// "Cell Height" /// "Fill Order" /// "Document Name" /// "Image Description" /// "Equip Make" /// "Equip Model" /// "Strip Offsets" /// "Orientation" /// "Samples PerPixel" /// "Rows Per Strip" /// "Strip Bytes Count" /// "Min Sample Value" /// "Max Sample Value" /// "X Resolution" /// "Y Resolution" /// "Planar Config" /// "Page Name" /// "X Position" /// "Y Position" /// "Free Offset" /// "Free Byte Counts" /// "Gray Response Unit" /// "Gray Response Curve" /// "T4 Option" /// "T6 Option" /// "Resolution Unit" /// "Page Number" /// "Transfer Funcition" /// "Software Used" /// "Date Time" /// "Artist" /// "Host Computer" /// "Predictor" /// "White Point" /// "Primary Chromaticities" /// "ColorMap" /// "Halftone Hints" /// "Tile Width" /// "Tile Length" /// "Tile Offset" /// "Tile ByteCounts" /// "InkSet" /// "Ink Names" /// "Number Of Inks" /// "Dot Range" /// "Target Printer" /// "Extra Samples" /// "Sample Format" /// "S Min Sample Value" /// "S Max Sample Value" /// "Transfer Range" /// "JPEG Proc" /// "JPEG InterFormat" /// "JPEG InterLength" /// "JPEG RestartInterval" /// "JPEG LosslessPredictors" /// "JPEG PointTransforms" /// "JPEG QTables" /// "JPEG DCTables" /// "JPEG ACTables" /// "YCbCr Coefficients" /// "YCbCr Subsampling" /// "YCbCr Positioning" /// "REF Black White" /// "ICC Profile" /// "Gamma" /// "ICC Profile Descriptor" /// "SRGB RenderingIntent" /// "Image Title" /// "Copyright" /// "Resolution X Unit" /// "Resolution Y Unit" /// "Resolution X LengthUnit" /// "Resolution Y LengthUnit" /// "Print Flags" /// "Print Flags Version" /// "Print Flags Crop" /// "Print Flags Bleed Width" /// "Print Flags Bleed Width Scale" /// "Halftone LPI" /// "Halftone LPIUnit" /// "Halftone Degree" /// "Halftone Shape" /// "Halftone Misc" /// "Halftone Screen" /// "JPEG Quality" /// "Grid Size" /// "Thumbnail Format" /// "Thumbnail Width" /// "Thumbnail Height" /// "Thumbnail ColorDepth" /// "Thumbnail Planes" /// "Thumbnail RawBytes" /// "Thumbnail Size" /// "Thumbnail CompressedSize" /// "Color Transfer Function" /// "Thumbnail Data" /// "Thumbnail ImageWidth" /// "Thumbnail ImageHeight" /// "Thumbnail BitsPerSample" /// "Thumbnail Compression" /// "Thumbnail PhotometricInterp" /// "Thumbnail ImageDescription" /// "Thumbnail EquipMake" /// "Thumbnail EquipModel" /// "Thumbnail StripOffsets" /// "Thumbnail Orientation" /// "Thumbnail SamplesPerPixel" /// "Thumbnail RowsPerStrip" /// "Thumbnail StripBytesCount" /// "Thumbnail ResolutionX" /// "Thumbnail ResolutionY" /// "Thumbnail PlanarConfig" /// "Thumbnail ResolutionUnit" /// "Thumbnail TransferFunction" /// "Thumbnail SoftwareUsed" /// "Thumbnail DateTime" /// "Thumbnail Artist" /// "Thumbnail WhitePoint" /// "Thumbnail PrimaryChromaticities" /// "Thumbnail YCbCrCoefficients" /// "Thumbnail YCbCrSubsampling" /// "Thumbnail YCbCrPositioning" /// "Thumbnail RefBlackWhite" /// "Thumbnail CopyRight" /// "Luminance Table" /// "Chrominance Table" /// "Frame Delay" /// "Loop Count" /// "Pixel Unit" /// "Pixel PerUnit X" /// "Pixel PerUnit Y" /// "Palette Histogram" /// "Exposure Time" /// "F-Number" /// "Exposure Prog" /// "Spectral Sense" /// "ISO Speed" /// "OECF" /// "Ver" /// "DTOrig" /// "DTDigitized" /// "CompConfig" /// "CompBPP" /// "Shutter Speed" /// "Aperture" /// "Brightness" /// "Exposure Bias" /// "MaxAperture" /// "SubjectDist" /// "Metering Mode" /// "LightSource" /// "Flash" /// "FocalLength" /// "Maker Note" /// "User Comment" /// "DTSubsec" /// "DTOrigSS" /// "DTDigSS" /// "FPXVer" /// "ColorSpace" /// "PixXDim" /// "PixYDim" /// "RelatedWav" /// "Interop" /// "FlashEnergy" /// "SpatialFR" /// "FocalXRes" /// "FocalYRes" /// "FocalResUnit" /// "Subject Loc" /// "Exposure Index" /// "Sensing Method" /// "FileSource" /// "SceneType" /// "CfaPattern" /// "Gps Ver" /// "Gps LatitudeRef" /// "Gps Latitude" /// "Gps LongitudeRef" /// "Gps Longitude" /// "Gps AltitudeRef" /// "Gps Altitude" /// "Gps GpsTime" /// "Gps GpsSatellites" /// "Gps GpsStatus" /// "Gps GpsMeasureMode" /// "Gps GpsDop" /// "Gps SpeedRef" /// "Gps Speed" /// "Gps TrackRef" /// "Gps Track" /// "Gps ImgDirRef" /// "Gps ImgDir" /// "Gps MapDatum" /// "Gps DestLatRef" /// "Gps DestLat" /// "Gps DestLongRef" /// "Gps DestLong" /// "Gps DestBearRef" /// "Gps DestBear" /// "Gps DestDistRef" /// "Gps DestDist" /// </summary> public object this[string index] { get { return properties[index]; } } // private System.Drawing.Bitmap bmp; // private string data; // private translation myHash; // private Hashtable properties; // internal int Count { get { return this.properties.Count; } } // string sp; /// <summary> /// /// </summary> /// <param name="id"></param> /// <param name="len"></param> /// <param name="type"></param> /// <param name="data"></param> public void setTag(int id, string data) { Encoding ascii = Encoding.ASCII; this.setTag(id,data.Length,0x2,ascii.GetBytes(data)); } /// <summary> /// /// </summary> /// <param name="id"></param> /// <param name="len"></param> /// <param name="type"></param> /// <param name="data"></param> public void setTag(int id, int len, short type, byte [] data) { PropertyItem p = CreatePropertyItem(type,id,len,data); this.bmp.SetPropertyItem( p ); buildDB(this.bmp.PropertyItems); } /// <summary> /// /// </summary> /// <param name="type"></param> /// <param name="tag"></param> /// <param name="len"></param> /// <param name="value"></param> /// <returns></returns> private static PropertyItem CreatePropertyItem(short type, int tag, int len, byte[] value) { PropertyItem item; // Loads a PropertyItem from a Jpeg image stored in the assembly as a resource. Assembly assembly = Assembly.GetExecutingAssembly(); Stream emptyBitmapStream = assembly.GetManifestResourceStream("EXIFextractor.decoy.jpg"); System.Drawing.Image empty = System.Drawing.Image.FromStream(emptyBitmapStream); item = empty.PropertyItems[0]; // Copies the data to the property item. item.Type = type; item.Len = len; item.Id = tag; item.Value = new byte[value.Length]; value.CopyTo(item.Value, 0); return item; } /// <summary> /// /// </summary> /// <param name="bmp"></param> /// <param name="sp"></param> public EXIFextractor(ref System.Drawing.Bitmap bmp, string sp ) { properties = new Hashtable(); // this.bmp = bmp; this.sp = sp; // myHash = new translation(); buildDB(this.bmp.PropertyItems); } string msp = ""; public EXIFextractor(ref System.Drawing.Bitmap bmp, string sp, string msp ) { properties = new Hashtable(); this.sp = sp; this.msp = msp; this.bmp = bmp; // myHash = new translation(); this.buildDB(bmp.PropertyItems); } public static void CopyTo(Stream input, Stream outputStream) { byte[] btybuffer = new byte[16 * 1019]; // Fairly arbitrary size int bytesRead; while ((bytesRead = input.Read(btybuffer, 0, btybuffer.Length)) > 0) { outputStream.Write(btybuffer, 0, bytesRead); } } public static PropertyItem[] GetExifProperties(string fileName) { MemoryStream ms = new MemoryStream(); using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { CopyTo(stream, ms); } System.Drawing.Image image = System.Drawing.Image.FromStream(ms, /* useEmbeddedColorManagement = */ true, /* validateImageData = */ false); return image.PropertyItems; } public EXIFextractor(string file, string sp, string msp ) { properties = new Hashtable(); this.sp = sp; this.msp = msp; myHash = new translation(); // this.buildDB(GetExifProperties(file)); } /// <summary> /// /// </summary> private void buildDB(System.Drawing.Imaging.PropertyItem[] parr) { properties.Clear(); // data = ""; // Encoding ascii = Encoding.ASCII; // foreach( System.Drawing.Imaging.PropertyItem p in parr ) { string v = ""; string name = (string)myHash[p.Id]; // tag not found. skip it if( name == null ) continue; // data += name+": "; // //1 = BYTE An 8-bit unsigned integer., if( p.Type == 0x1 ) { v = p.Value[0].ToString(); } //2 = ASCII An 8-bit byte containing one 7-bit ASCII code. The final byte is terminated with NULL., else if( p.Type == 0x2 ) { // string v = ascii.GetString(p.Value); } //3 = SHORT A 16-bit (2 -byte) unsigned integer, else if( p.Type == 0x3 ) { // orientation // lookup table switch( p.Id ) { case 0x8827: // ISO v = "ISO-" + convertToInt16U(p.Value).ToString(); break; case 0xA217: // sensing method { switch( convertToInt16U(p.Value) ) { case 1: v = "Not defined"; break; case 2: v = "One-chip color area sensor"; break; case 3: v = "Two-chip color area sensor"; break; case 4: v = "Three-chip color area sensor"; break; case 5: v = "Color sequential area sensor"; break; case 7: v = "Trilinear sensor"; break; case 8: v = "Color sequential linear sensor"; break; default: v =" reserved"; break; } } break; case 0x8822: // aperture switch( convertToInt16U(p.Value) ) { case 0: v = "Not defined"; break; case 1: v = "Manual"; break; case 2: v = "Normal program"; break; case 3: v = "Aperture priority"; break; case 4: v = "Shutter priority"; break; case 5: v = "Creative program (biased toward depth of field)"; break; case 6: v = "Action program (biased toward fast shutter speed)"; break; case 7: v = "Portrait mode (for closeup photos with the background out of focus)"; break; case 8: v = "Landscape mode (for landscape photos with the background in focus)"; break; default: v = "reserved"; break; } break; case 0x9207: // metering mode switch( convertToInt16U(p.Value) ) { case 0: v = "unknown";break; case 1: v = "Average";break; case 2: v = "CenterWeightedAverage"; break; case 3: v = "Spot"; break; case 4: v = "MultiSpot"; break; case 5: v = "Pattern"; break; case 6: v = "Partial"; break; case 255: v = "Other"; break; default: v = "reserved"; break; } break; case 0x9208: // light source { switch(convertToInt16U(p.Value) ) { case 0:v = "unknown";break; case 1:v = "Daylight";break; case 2:v = "Fluorescent";break; case 3:v = "Tungsten";break; case 17:v = "Standard light A";break; case 18:v = "Standard light B";break; case 19:v = "Standard light C";break; case 20:v = "D55";break; case 21:v = "D65";break; case 22:v = "D75";break; case 255:v = "other";break; default:v = "reserved";break; } } break; case 0x9209: { switch(convertToInt16U(p.Value) ) { case 0: v = "Flash did not fire"; break; case 1: v = "Flash fired"; break; case 5: v = "Strobe return light not detected"; break; case 7: v = "Strobe return light detected"; break; default: v = "reserved"; break; } } break; default: v = convertToInt16U(p.Value).ToString(); break; } } //4 = LONG A 32-bit (4 -byte) unsigned integer, else if( p.Type == 0x4 ) { // orientation // lookup table v = convertToInt32U(p.Value).ToString(); } //5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the//denominator., else if( p.Type == 0x5 ) { //My code starts here if (p.Id == 0x0004) { //lat // rational byte[] deg = new byte[4]; byte[] degdiv = new byte[4]; byte[] min = new byte[4]; byte[] mindiv = new byte[4]; byte[] sec = new byte[4]; byte[] secdiv = new byte[4]; Array.Copy(p.Value, 0, deg, 0, 4); Array.Copy(p.Value, 4, degdiv, 0, 4); Array.Copy(p.Value, 8, min, 0, 4); Array.Copy(p.Value, 12, mindiv, 0, 4); Array.Copy(p.Value, 16, sec, 0, 4); Array.Copy(p.Value, 20, secdiv, 0, 4); double _a = convertToInt32U(deg); double _b = convertToInt32U(degdiv); double _c = convertToInt32U(min); double _d = convertToInt32U(mindiv); double _e = convertToInt32U(sec); double _f = convertToInt32U(secdiv); double _o = ((_a / _b) + ((_c / _b) / 60) + ((_e / _f) / 3600)); v = _o.ToString(); // Rational r = new Rational(a, b); } else if (p.Id == 0x0002) { //long byte[] deg = new byte[4]; byte[] degdiv = new byte[4]; byte[] min = new byte[4]; byte[] mindiv = new byte[4]; byte[] sec = new byte[4]; byte[] secdiv = new byte[4]; Array.Copy(p.Value, 0, deg, 0, 4); Array.Copy(p.Value, 4, degdiv, 0, 4); Array.Copy(p.Value, 8, min, 0, 4); Array.Copy(p.Value, 12, mindiv, 0, 4); Array.Copy(p.Value, 16, sec, 0, 4); Array.Copy(p.Value, 20, secdiv, 0, 4); double dblA = convertToInt32U(deg); double dblB = convertToInt32U(degdiv); double dblC = convertToInt32U(min); double dblD = convertToInt32U(mindiv); double dblE = convertToInt32U(sec); double dblF = convertToInt32U(secdiv); double o = ((dblA / dblB) + ((dblC/ dblB) / 60) + ((dblE/ dblF) / 3600)); v = o.ToString(); } //My Code ends here // rational byte[]n = new byte[p.Len/2]; byte []d = new byte[p.Len/2]; Array.Copy(p.Value,0,n,0,p.Len/2); Array.Copy(p.Value,p.Len/2,d,0,p.Len/2); uint a = convertToInt32U(n); uint b = convertToInt32U(d); Rational r = new Rational(a,b); // //convert here // switch( p.Id ) { case 0x9202: // aperture v = "F/" + Math.Round(Math.Pow(Math.Sqrt(2),r.ToDouble()),2).ToString(); break; case 0x920A: v = r.ToDouble().ToString(); break; case 0x829A: v = r.ToDouble().ToString(); break; case 0x829D: // F-number v = "F/" + r.ToDouble().ToString(); break; default: v= r.ToString("/"); break; } } //7 = UNDEFINED An 8-bit byte that can take any value depending on the field definition, else if( p.Type == 0x7 ) { switch (p.Id ) { case 0xA300: { if( p.Value[0] == 3 ) { v = "DSC"; } else { v = "reserved"; } break; } case 0xA301: if( p.Value[0] == 1 ) v = "A directly photographed image"; else v = "Not a directly photographed image"; break; default: v = "-"; break; } } //9 = SLONG A 32-bit (4 -byte) signed integer (2's complement notation), else if( p.Type == 0x9 ) { v = convertToInt32(p.Value).ToString(); } //10 = SRATIONAL Two SLONGs. The first SLONG is the numerator and the second SLONG is the //denominator. else if( p.Type == 0xA ) { // rational byte []n = new byte[p.Len/2]; byte []d = new byte[p.Len/2]; Array.Copy(p.Value,0,n,0,p.Len/2); Array.Copy(p.Value,p.Len/2,d,0,p.Len/2); int a = convertToInt32(n); int b = convertToInt32(d); Rational r = new Rational(a,b); // // convert here // switch( p.Id ) { case 0x9201: // shutter speed v = "1/" +Math.Round( Math.Pow(2,r.ToDouble()),2).ToString(); break; case 0x9203: v = Math.Round(r.ToDouble(),4).ToString(); break; default: v = r.ToString("/"); break; } } // add it to the list if( properties[name] == null ) properties.Add(name,v); // cat it too data+= v; data+= this.sp; } } /// <summary> /// /// </summary> /// <returns></returns> public override string ToString() { return data; } /// <summary> /// /// </summary> /// <param name="arr"></param> /// <returns></returns> int convertToInt32(byte [] arr) { if(arr.Length != 4 ) return 0; else return arr[3] << 24 | arr[2] << 16 | arr[1] << 8 | arr[0]; } /// <summary> /// /// </summary> /// <param name="arr"></param> /// <returns></returns> int convertToInt16(byte [] arr) { if(arr.Length != 2 ) return 0; else return arr[1] << 8 | arr[0]; } /// <summary> /// /// </summary> /// <param name="arr"></param> /// <returns></returns> uint convertToInt32U(byte [] arr) { if(arr.Length != 4 ) return 0; else return Convert.ToUInt32(arr[3] << 24 | arr[2] << 16 | arr[1] << 8 | arr[0]); } /// <summary> /// /// </summary> /// <param name="arr"></param> /// <returns></returns> uint convertToInt16U(byte [] arr) { if(arr.Length != 2 ) return 0; else return Convert.ToUInt16(arr[1] << 8 | arr[0]); } #region IEnumerable Members public IEnumerator GetEnumerator() { // TODO: Add EXIFextractor.GetEnumerator implementation return( new EXIFextractorEnumerator( this.properties )); } #endregion } // // dont touch this class. its for IEnumerator // // class EXIFextractorEnumerator : IEnumerator { Hashtable exifTable; IDictionaryEnumerator index; internal EXIFextractorEnumerator( Hashtable exif ) { this.exifTable = exif; this.Reset(); index = exif.GetEnumerator(); } #region IEnumerator Members public void Reset() { this.index = null; } public object Current { get { return ( new System.Web.UI.Pair(this.index.Key,this.index.Value) ); } } public bool MoveNext() { if( index != null && index.MoveNext() ) return true; else return false; } #endregion } }
А вот код для моего класса перевода.
using System; using System.Collections; namespace EXIF { /// <summary> /// Summary description for translation. /// </summary> public class translation : Hashtable { /// <summary> /// /// </summary> public translation() { this.Add(0x8769,"Exif IFD"); this.Add(0x8825,"Gps IFD"); this.Add(0xFE,"New Subfile Type"); this.Add(0xFF,"Subfile Type"); this.Add(0x100,"Image Width"); this.Add(0x101,"Image Height"); this.Add(0x102,"Bits Per Sample"); this.Add(0x103,"Compression"); this.Add(0x106,"Photometric Interp"); this.Add(0x107,"Thresh Holding"); this.Add(0x108,"Cell Width"); this.Add(0x109,"Cell Height"); this.Add(0x10A,"Fill Order"); this.Add(0x10D,"Document Name"); this.Add(0x10E,"Image Description"); this.Add(0x10F,"Equip Make"); this.Add(0x110,"Equip Model"); this.Add(0x111,"Strip Offsets"); this.Add(0x112,"Orientation"); this.Add(0x115,"Samples PerPixel"); this.Add(0x116,"Rows Per Strip"); this.Add(0x117,"Strip Bytes Count"); this.Add(0x118,"Min Sample Value"); this.Add(0x119,"Max Sample Value"); this.Add(0x11A,"X Resolution"); this.Add(0x11B,"Y Resolution"); this.Add(0x11C,"Planar Config"); this.Add(0x11D,"Page Name"); this.Add(0x11E,"X Position"); this.Add(0x11F,"Y Position"); this.Add(0x120,"Free Offset"); this.Add(0x121,"Free Byte Counts"); this.Add(0x122,"Gray Response Unit"); this.Add(0x123,"Gray Response Curve"); this.Add(0x124,"T4 Option"); this.Add(0x125,"T6 Option"); this.Add(0x128,"Resolution Unit"); this.Add(0x129,"Page Number"); this.Add(0x12D,"Transfer Funcition"); this.Add(0x131,"Software Used"); this.Add(0x132,"Date Time"); this.Add(0x13B,"Artist"); this.Add(0x13C,"Host Computer"); this.Add(0x13D,"Predictor"); this.Add(0x13E,"White Point"); this.Add(0x13F,"Primary Chromaticities"); this.Add(0x140,"ColorMap"); this.Add(0x141,"Halftone Hints"); this.Add(0x142,"Tile Width"); this.Add(0x143,"Tile Length"); this.Add(0x144,"Tile Offset"); this.Add(0x145,"Tile ByteCounts"); this.Add(0x14C,"InkSet"); this.Add(0x14D,"Ink Names"); this.Add(0x14E,"Number Of Inks"); this.Add(0x150,"Dot Range"); this.Add(0x151,"Target Printer"); this.Add(0x152,"Extra Samples"); this.Add(0x153,"Sample Format"); this.Add(0x154,"S Min Sample Value"); this.Add(0x155,"S Max Sample Value"); this.Add(0x156,"Transfer Range"); this.Add(0x200,"JPEG Proc"); this.Add(0x201,"JPEG InterFormat"); this.Add(0x202,"JPEG InterLength"); this.Add(0x203,"JPEG RestartInterval"); this.Add(0x205,"JPEG LosslessPredictors"); this.Add(0x206,"JPEG PointTransforms"); this.Add(0x207,"JPEG QTables"); this.Add(0x208,"JPEG DCTables"); this.Add(0x209,"JPEG ACTables"); this.Add(0x211,"YCbCr Coefficients"); this.Add(0x212,"YCbCr Subsampling"); this.Add(0x213,"YCbCr Positioning"); this.Add(0x214,"REF Black White"); this.Add(0x8773,"ICC Profile"); this.Add(0x301,"Gamma"); this.Add(0x302,"ICC Profile Descriptor"); this.Add(0x303,"SRGB RenderingIntent"); this.Add(0x320,"Image Title"); this.Add(0x8298,"Copyright"); this.Add(0x5001,"Resolution X Unit"); this.Add(0x5002,"Resolution Y Unit"); this.Add(0x5003,"Resolution X LengthUnit"); this.Add(0x5004,"Resolution Y LengthUnit"); this.Add(0x5005,"Print Flags"); this.Add(0x5006,"Print Flags Version"); this.Add(0x5007,"Print Flags Crop"); this.Add(0x5008,"Print Flags Bleed Width"); this.Add(0x5009,"Print Flags Bleed Width Scale"); this.Add(0x500A,"Halftone LPI"); this.Add(0x500B,"Halftone LPIUnit"); this.Add(0x500C,"Halftone Degree"); this.Add(0x500D,"Halftone Shape"); this.Add(0x500E,"Halftone Misc"); this.Add(0x500F,"Halftone Screen"); this.Add(0x5010,"JPEG Quality"); this.Add(0x5011,"Grid Size"); this.Add(0x5012,"Thumbnail Format"); this.Add(0x5013,"Thumbnail Width"); this.Add(0x5014,"Thumbnail Height"); this.Add(0x5015,"Thumbnail ColorDepth"); this.Add(0x5016,"Thumbnail Planes"); this.Add(0x5017,"Thumbnail RawBytes"); this.Add(0x5018,"Thumbnail Size"); this.Add(0x5019,"Thumbnail CompressedSize"); this.Add(0x501A,"Color Transfer Function"); this.Add(0x501B,"Thumbnail Data"); this.Add(0x5020,"Thumbnail ImageWidth"); this.Add(0x502,"Thumbnail ImageHeight"); this.Add(0x5022,"Thumbnail BitsPerSample"); this.Add(0x5023,"Thumbnail Compression"); this.Add(0x5024,"Thumbnail PhotometricInterp"); this.Add(0x5025,"Thumbnail ImageDescription"); this.Add(0x5026,"Thumbnail EquipMake"); this.Add(0x5027,"Thumbnail EquipModel"); this.Add(0x5028,"Thumbnail StripOffsets"); this.Add(0x5029,"Thumbnail Orientation"); this.Add(0x502A,"Thumbnail SamplesPerPixel"); this.Add(0x502B,"Thumbnail RowsPerStrip"); this.Add(0x502C,"Thumbnail StripBytesCount"); this.Add(0x502D,"Thumbnail ResolutionX"); this.Add(0x502E,"Thumbnail ResolutionY"); this.Add(0x502F,"Thumbnail PlanarConfig"); this.Add(0x5030,"Thumbnail ResolutionUnit"); this.Add(0x5031,"Thumbnail TransferFunction"); this.Add(0x5032,"Thumbnail SoftwareUsed"); this.Add(0x5033,"Thumbnail DateTime"); this.Add(0x5034,"Thumbnail Artist"); this.Add(0x5035,"Thumbnail WhitePoint"); this.Add(0x5036,"Thumbnail PrimaryChromaticities"); this.Add(0x5037,"Thumbnail YCbCrCoefficients"); this.Add(0x5038,"Thumbnail YCbCrSubsampling"); this.Add(0x5039,"Thumbnail YCbCrPositioning"); this.Add(0x503A,"Thumbnail RefBlackWhite"); this.Add(0x503B,"Thumbnail CopyRight"); this.Add(0x5090,"Luminance Table"); this.Add(0x5091,"Chrominance Table"); this.Add(0x5100,"Frame Delay"); this.Add(0x5101,"Loop Count"); this.Add(0x5110,"Pixel Unit"); this.Add(0x5111,"Pixel PerUnit X"); this.Add(0x5112,"Pixel PerUnit Y"); this.Add(0x5113,"Palette Histogram"); this.Add(0x829A,"Exposure Time"); this.Add(0x829D,"F-Number"); this.Add(0x8822,"Exposure Prog"); this.Add(0x8824,"Spectral Sense"); this.Add(0x8827,"ISO Speed"); this.Add(0x8828,"OECF"); this.Add(0x9000,"Ver"); this.Add(0x9003,"DTOrig"); this.Add(0x9004,"DTDigitized"); this.Add(0x9101,"CompConfig"); this.Add(0x9102,"CompBPP"); this.Add(0x9201,"Shutter Speed"); this.Add(0x9202,"Aperture"); this.Add(0x9203,"Brightness"); this.Add(0x9204,"Exposure Bias"); this.Add(0x9205,"MaxAperture"); this.Add(0x9206,"SubjectDist"); this.Add(0x9207,"Metering Mode"); this.Add(0x9208,"LightSource"); this.Add(0x9209,"Flash"); this.Add(0x920A,"FocalLength"); this.Add(0x927C,"Maker Note"); this.Add(0x9286,"User Comment"); this.Add(0x9290,"DTSubsec"); this.Add(0x9291,"DTOrigSS"); this.Add(0x9292,"DTDigSS"); this.Add(0xA000,"FPXVer"); this.Add(0xA001,"ColorSpace"); this.Add(0xA002,"PixXDim"); this.Add(0xA003,"PixYDim"); this.Add(0xA004,"RelatedWav"); this.Add(0xA005,"Interop"); this.Add(0xA20B,"FlashEnergy"); this.Add(0xA20C,"SpatialFR"); this.Add(0xA20E,"FocalXRes"); this.Add(0xA20F,"FocalYRes"); this.Add(0xA210,"FocalResUnit"); this.Add(0xA214,"Subject Loc"); this.Add(0xA215,"Exposure Index"); this.Add(0xA217,"Sensing Method"); this.Add(0xA300,"FileSource"); this.Add(0xA301,"SceneType"); this.Add(0xA302,"CfaPattern"); this.Add(0x0,"Gps Ver"); this.Add(0x1,"Gps LatitudeRef"); this.Add(0x2,"Gps Latitude"); this.Add(0x3,"Gps LongitudeRef"); this.Add(0x4,"Gps Longitude"); this.Add(0x5,"Gps AltitudeRef"); this.Add(0x6,"Gps Altitude"); this.Add(0x7,"Gps GpsTime"); this.Add(0x8,"Gps GpsSatellites"); this.Add(0x9,"Gps GpsStatus"); this.Add(0xA,"Gps GpsMeasureMode"); this.Add(0xB,"Gps GpsDop"); this.Add(0xC,"Gps SpeedRef"); this.Add(0xD,"Gps Speed"); this.Add(0xE,"Gps TrackRef"); this.Add(0xF,"Gps Track"); this.Add(0x10,"Gps ImgDirRef"); this.Add(0x11,"Gps ImgDir"); this.Add(0x12,"Gps MapDatum"); this.Add(0x13,"Gps DestLatRef"); this.Add(0x14,"Gps DestLat"); this.Add(0x15,"Gps DestLongRef"); this.Add(0x16,"Gps DestLong"); this.Add(0x17,"Gps DestBearRef"); this.Add(0x18,"Gps DestBear"); this.Add(0x19,"Gps DestDistRef"); this.Add(0x1A,"Gps DestDist"); } } /// <summary> /// private class /// </summary> internal class Rational { private int n; private int d; public Rational(int n, int d) { this.n = n; this.d = d; simplify(ref this.n, ref this.d); } public Rational(uint n, uint d) { this.n = Convert.ToInt32(n); this.d = Convert.ToInt32(d); simplify(ref this.n, ref this.d); } public Rational() { this.n= this.d=0; } public string ToString(string sp) { if( sp == null ) sp = "/"; return n.ToString() + sp + d.ToString(); } public double ToDouble() { if( d == 0 ) return 0.0; return Math.Round(Convert.ToDouble(n)/Convert.ToDouble(d),2); } private void simplify( ref int a, ref int b ) { if( a== 0 || b == 0 ) return; int gcd = euclid(a,b); a /= gcd; b /= gcd; } private int euclid(int a, int b) { if(b==0) return a; else return euclid(b,a%b); } } }
Что я уже пробовал:
Я уже смотрел класс PropertyItem в msdn, но не знаю, с чего начать его реализацию для этой программы.
Что-то подсказывает мне, что я должен настроить оператор if else для тега в EXIFextractor.BuildDB(). Но, увы, математика не является моей сильной стороной. Как бы мне реализовать эту логику, пожалуйста?
Richard MacCutchan
Сообщение об ошибке совершенно ясно, ваш bmp
переменная никогда не была установлена в допустимую ссылку на объект. Но где во всем этом коде возникает ошибка, не ясно.
Jordan Nash
Ах, да, я понимаю, что у меня была перегрузка метода точного метода, где была ошибка. Это здесь, в Эксифэкстракторе.
public void setTag(int id, int len, short type, byte [] data)
{
PropertyItem p = CreatePropertyItem(тип,идентификатор,len,данные);
this.bmp.SetPropertyItem( p );//ошибка в этой строке.
buildDB(this.bmp.PropertyItems);
}
Richard MacCutchan
Поэтому вам нужно выяснить, почему bmp не установлен в допустимую ссылку.
Jordan Nash
Я изменил метод loadImageMetaData() на этот. Метод setTag (), конечно, ожидал растрового изображения, поэтому я создал его экземпляр.
частный недействительными loadImageMetaData()
{
lstImageMetaData.Предметы.Четкий();
Bitmap bmp = новое растровое изображение(_big_fileName);
ЭКСИФ.EXIFextractor er2 = новый EXIF.EXIFextractor(ref bmp, "\n");
foreach (пара s в er2)
{
lstImageMetaData.Предметы.Добавить(s.First + " : "+ s.Second);
}
lstImageMetaData.Свойства selectedIndex = lstImageMetaData.Предметы.Количество - 1;
er2.setTag(0x5013,"ширина миниатюры");
}
Итак, я больше не получаю ошибку, но она по-прежнему не будет отображать метаданные “ширина миниатюры”. Вы знаете, что я делаю не так, пожалуйста?
Richard MacCutchan
Эта библиотека была написана членом CodeProject, поэтому вам нужно разместить свой вопрос на форуме в конце статьи.
Jordan Nash
Я уже сделал это 3 дня назад. Никто не ответил. Возможно, мне нужно больше терпения. Я поставлю свой предыдущий комментарий отсюда на тот вопрос, который я уже разместил на этом форуме.
Richard MacCutchan
Проблема в том, что человек, написавший эту статью, - единственный, кто действительно поймет, как она работает. Так что, спрашивая здесь, вы вряд ли получите ответ.