|
|
Im working on a website about photos... which already runs with this guy right here (jquery plug and show...) I wonder how to implement and use the same class to display the exif data for (each) & all those photos from catalogs....
ANY ideea would be realy apreciated, i'm new to .net and c# ((
thanks
|
|
|
|
|
Can I use some kind of a ffmpeg mono wrapper to convert videos?
modified on Wednesday, September 21, 2011 6:09 AM
|
|
|
|
|
Hi!
I used the dll and it works great so far.
Now I want to change the recording date ("Aufnahmedatum" in German) which is shown in windows 7 as info in the explorer when the image is selected.
I tried to change DTOrig, DTDigitized and Date Time but none of those is the right entry.
Does anyone know which one that is?
Thanks for any help,
Herb
Herb
|
|
|
|
|
Thanks for sharing! Steve Jobs needs to adopt your attitude.
|
|
|
|
|
Does exactly what it says it would, is well documented, is freely available.
|
|
|
|
|
I was using the binary DLL which locks the file..
I now use the source version of the DLL which is corrected.
Could you update the binary version ?
Thanks!
|
|
|
|
|
This article is great but..
Is seems form this forum that you cannot move, delete or rename a file after ExifExtrator.
Where is the modified Dll version ?
Thanks.
|
|
|
|
|
try to update the GetExifProperties method and rebuild the solution
public static PropertyItem[] GetExifProperties(string fileName)
{
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
System.Drawing.Image image = System.Drawing.Image.FromStream(
stream,
true,
false);
return image.PropertyItems;
}
}
|
|
|
|
|
Excellent work man!
was working hard for such a class of my own for my software... but u got it right!! great help!
|
|
|
|
|
When Im trying to get the exposure time it returns zero, I expected it to return 1/180 sec or something like that. I have uploaded a test picture, and it can be found here: http://qaz.dk/nydraabe.jpg
I also tried to get shutter speed but i returns null.
|
|
|
|
|
I uncomented example code and set path to my own jpg.
When THIS LINE
er.setTag(0x320, "http://www.beautifulpakistan.com");
was calling, exception System.ArgumentException was thrown in this function.
private static PropertyItem CreatePropertyItem(short type, int tag, int len, byte[] value)
{
PropertyItem item;
Assembly assembly = Assembly.GetExecutingAssembly();
Stream emptyBitmapStream = assembly.GetManifestResourceStream("EXIFextractor.decoy.jpg");
System.Drawing.Image empty = System.Drawing.Image.FromStream(emptyBitmapStream);
item = empty.PropertyItems[0];
item.Type = type;
item.Len = len;
item.Id = tag;
item.Value = new byte[value.Length];
value.CopyTo(item.Value, 0);
return item;
}
emptyBitmapStream was null.
What is wrong?
|
|
|
|
|
If a picture has 1/125 shutter speed, your code wil return 1/125.37 instead.
|
|
|
|
|
I cannot find the way of doing that because image.PropertyItems doesn't exist in CF.
Thanks
|
|
|
|
|
For those of you who require the GPS info. In the EXIFextractor.cs after
<br />
else if( p.Type == 0x5 )<br />
{<br />
I inserted this:
<br />
…<br />
else if( p.Type == 0x5 )<br />
{<br />
if (p.Id == 0x0004)<br />
{<br />
byte[] deg = new byte[4];<br />
byte[] degdiv = new byte[4];<br />
byte[] min = new byte[4];<br />
byte[] mindiv = new byte[4];<br />
byte[] sec = new byte[4];<br />
byte[] secdiv = new byte[4];<br />
Array.Copy(p.Value, 0, deg, 0, 4);<br />
Array.Copy(p.Value, 4, degdiv, 0, 4);<br />
Array.Copy(p.Value, 8, min, 0, 4);<br />
Array.Copy(p.Value, 12, mindiv, 0, 4);<br />
Array.Copy(p.Value, 16, sec, 0, 4);<br />
Array.Copy(p.Value, 20, secdiv, 0, 4);<br />
double a = convertToInt32U(deg);<br />
double b = convertToInt32U(degdiv);<br />
double c = convertToInt32U(min);<br />
double d = convertToInt32U(mindiv);<br />
double e = convertToInt32U(sec);<br />
double f = convertToInt32U(secdiv);<br />
double o =((a/b) + ((c/b)/60) + ((e/f)/3600));<br />
v = o.ToString();<br />
}<br />
else if (p.Id == 0x0002)<br />
{<br />
byte[] deg = new byte[4];<br />
byte[] degdiv = new byte[4];<br />
byte[] min = new byte[4];<br />
byte[] mindiv = new byte[4];<br />
byte[] sec = new byte[4];<br />
byte[] secdiv = new byte[4];<br />
Array.Copy(p.Value, 0, deg, 0, 4);<br />
Array.Copy(p.Value, 4, degdiv, 0, 4);<br />
Array.Copy(p.Value, 8, min, 0, 4);<br />
Array.Copy(p.Value, 12, mindiv, 0, 4);<br />
Array.Copy(p.Value, 16, sec, 0, 4);<br />
Array.Copy(p.Value, 20, secdiv, 0, 4);<br />
double a = convertToInt32U(deg);<br />
double b = convertToInt32U(degdiv);<br />
double c = convertToInt32U(min);<br />
double d = convertToInt32U(mindiv);<br />
double e = convertToInt32U(sec);<br />
double f = convertToInt32U(secdiv);<br />
double o = ((a / b) + ((c / b) / 60) + ((e / f) / 3600));<br />
v = o.ToString();<br />
}<br />
else<br />
{<br />
byte[] n = new byte[p.Len / 2];<br />
…<br />
Not perfect but it returns valid coordinates
Some Info on how this works:
The GPS coordinates come in as rational byte arrays
d d d d x x x x m m m m x x x x s s s s x x x x
55 0 0 0 1 0 0 0 37 22 0 0 100 0 0 0 0 0 0 0 1 0 0 0
55.94483 is...
55 0 0 0 = 55 / 1 = 55 Degrees
1 0 0 0
37 22 0 0 = 5669 / 100 = 56.69 Minutes (56.69 Minutes / 60 = 0.94483 Degrees)
100 0 0 0
0 0 0 0 = 0 / 1 = 0.0 Seconds (0 Seconds / 3600 = 0 Degrees)
1 0 0 0
modified on Thursday, April 24, 2008 7:11 AM
|
|
|
|
|
Thanks a lot!! It works great
|
|
|
|
|
This is great, many thanks. I added the code you posted for GPS data, but it doesnt seem to recognise the sign, ie. -117 degrees or +117 degrees? Will look at this, but any ideas appreciated.
Rob
|
|
|
|
|
Ok, you can figure out if it is + or minus by reading the Gps LongitudeRef or Gps LatitudeRef.
|
|
|
|
|
For all Germans who need a conversion from WGS84 to Gauss Krueger I post my solution which works great:
public Int16 Transform_WGS84_2_GK ( double rLatDec, double rLonDec, double rH, ref double rLongitude, ref double rLatitude)
{
double rWGS_a = 6378137.000;
double rWGS_b = 6356752.314;
double Bessel_a = 6377397.155;
double Bessel_b = 6356078.962;
double TPdx = 598.1;
double TPdy = 73.7;
double TPdz = 418.2;
double TPex = -0.202;
double TPey = -0.045;
double TPez = 2.455;
double TPm = 6.7;
double rWGS_E2, rWGS_N;
double rVecX, rVecY, rVecZ;
double F2, F3, F4, F5, F6, F7, F8;
double rotVec1,rotVec2, rotVec3;
double trans1, trans2, trans3;
double s5;
double T5;
double B5;
double L5;
double N5;
double h5,B,L,h;
double Bessel_e2;
double n6, alpha, beta, gamma, delta, epsilon;
int L0;
double l6, B6, N6_, nano, t6;
double Bogenlaenge;
double h1,h2,r1,r2;
rWGS_E2 = ( Sqr(rWGS_a) - Sqr(rWGS_b))/ (Sqr(rWGS_a));
rWGS_N = (rWGS_a)/(Math.Sqrt( 1 - rWGS_E2*Sqr(Math.Sin( rLatDec/180*Math.PI))));
rVecX = (rWGS_N + rH) * Math.Cos(rLatDec / 180 * Math.PI) * Math.Cos(rLonDec / 180 * Math.PI);
rVecY = (rWGS_N + rH) * Math.Cos(rLatDec / 180 * Math.PI) * Math.Sin(rLonDec / 180 * Math.PI);
rVecZ = ( rWGS_N * Sqr(rWGS_b)/Sqr( rWGS_a) + rH) * Math.Sin( rLatDec / 180 * Math.PI);
F5 = -TPex * Math.PI / 180 / 3600;
F6 = -TPey * Math.PI / 180 / 3600;
F7 = -TPez * Math.PI / 180 / 3600;
F8 = 1 - TPm/1000000;
F2 = -( TPdx + F7*TPdy - F6*TPdz);
F3 = -(-F7*TPdx + TPdy + F5*TPdz);
F4 = -( F6*TPdx - F5*TPdy + TPdz);
rotVec1 = ( rVecX + F7*rVecY - F6*rVecZ) * F8;
rotVec2 = (-F7*rVecX + rVecY + F5*rVecZ) * F8;
rotVec3 = ( F6*rVecX - F5*rVecY + rVecZ) * F8;
trans1 = rotVec1 + F2;
trans2 = rotVec2 + F3;
trans3 = rotVec3 + F4;
s5 = Math.Sqrt(Sqr(trans1) + Sqr(trans2));
Bessel_e2 = (Sqr(Bessel_a)-Sqr(Bessel_b))/Sqr(Bessel_a);
T5 = Math.Atan( trans3 * Bessel_a / (s5 * Bessel_b));
B5 = Math.Atan((trans3 + Bessel_e2 * Sqr(Bessel_a) / Bessel_b * Math.Pow(Math.Sin(T5), 3)) / (s5 - Bessel_e2 * Bessel_a * Math.Pow(Math.Cos(T5), 3)));
L5 = Math.Atan( trans2 / trans1);
N5 = Bessel_a/Math.Sqrt(1-Bessel_e2 * Sqr(Math.Sin(B5)));
h5 = (s5 / Math.Cos(B5)) - N5;
B = B5 * 180 / Math.PI;
L = L5 * 180 / Math.PI;
h = h5;
n6 = (Bessel_a - Bessel_b)/(Bessel_a + Bessel_b);
alpha = ((Bessel_a + Bessel_b)/2) * ( 1 + 0.25*Sqr(n6) + 1/64*Math.Pow(n6,4));
beta = -1.5*n6 + 9/16*Math.Pow(n6,3) - 3/32*Math.Pow(n6,5);
gamma = 15/16 * Sqr(n6) - 15/32*Math.Pow(n6,4);
delta = -35/48*Math.Pow(n6,3) + 105/256*Math.Pow(n6,5);
epsilon = 315/512*Math.Pow(n6,4);
if( Math.Abs(L-6) < 1.5)
L0 = 6;
else if (Math.Abs(L - 9) < 1.5)
L0 = 9;
else if (Math.Abs(L - 12) < 1.5)
L0 = 12;
else if (Math.Abs(L - 15) < 1.5)
L0 = 15;
else
{
MessageBox.Show( "Länge nicht unterstützt! Koordinatentransformation nur für Deutschland!");
L0 = -1;
}
if (L0 > 0)
{
l6 = (L - L0) * Math.PI / 180;
B6 = B * Math.PI / 180;
N6_ = Bessel_a / Math.Sqrt(1 - Bessel_e2 * Sqr(Math.Sin(B6)));
nano = Math.Sqrt(Sqr(Bessel_a) / Sqr(Bessel_b) * Bessel_e2 * Sqr(Math.Cos(B6)));
t6 = Math.Tan(B6);
Bogenlaenge = alpha * (B6 + beta * Math.Sin(2 * B6) + gamma * Math.Sin(4 * B6) + delta * Math.Sin(6 * B6) + epsilon * Math.Sin(8 * B6));
h1 = t6 / 2 * N6_ * Sqr(Math.Cos(B6)) * Sqr(l6);
h2 = t6 / 24 * N6_ * Math.Pow(Math.Cos(B6), 4) * (5 - Sqr(t6) + 9 * Sqr(nano) + 4 * Math.Pow(nano, 4)) * Math.Pow(l6, 4);
// h3 := t6/720*N6_*Power(Cos(B6),6)*(61 - 58*Sqr(t6) + 270*Sqr(nano) - 330*Sqr(t6)*Sqr(nano))*Power(l6,6);
// h4 := t6/40320*N6_*Power(Cos(B6),8)*(1385-3111*Sqr(t6) + 543*Power(t6,4) - Power(t6,6))*Power(l6,8);
rLatitude = Bogenlaenge + h1 + h2;
r1 = N6_ * Math.Cos(B6) * l6;
r2 = N6_ / 6 * Math.Pow(Math.Cos(B6), 3) * (1 - Sqr(t6) + Sqr(nano)) * Math.Pow(l6, 3);
rLongitude = r1 + r2 + 500000 + L0 / 3 * 1000000;
}
return 0;
}
private double Sqr(double r)
{
return ( Math.Pow( r, 2.0));
}
|
|
|
|
|
Hi, Exist a little bug in:
double o = ((a / b) + ((c / b) / 60) + ((e / f) / 3600));
it would to be
double o = ((a / b) + ((c / d) / 60) + ((e / f) / 3600));
Best Regards,
Mario
|
|
|
|
|
hi,thank you for ur gps code n for the author coding,i manage to add it into
another program
but there is a problem --> [b]Field '.myHash' is never assigned to,and will
always have its default value null[/b]
how should i set it?
|
|
|
|
|
I used your code it works amazingly well. Could you please tell me where you learned to format tags and display them. Do you have any link or resources you used, plaease?
|
|
|
|
|
I experienced problem calculating md5 of image immediately after using this library for read EXIF. After analyzing the problem I think there is a bug in this library. The following method must be modified to correct it (FileStream is being closed explicitly):
public static PropertyItem[] GetExifProperties(string fileName)
{
FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
System.Drawing.Image image = System.Drawing.Image.FromStream(stream,
/* useEmbeddedColorManagement = */ true,
/* validateImageData = */ false);
PropertyItem[] pi = image.PropertyItems;
stream.Close();
return pi;
}
|
|
|
|
|
Here is the fix for your file locked issue:
public static PropertyItem[] GetExifProperties(string fileName, out long size)
{
using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
size = stream.Length;
using (System.Drawing.Image image = System.Drawing.Image.FromStream(stream, true, false))
{
return image.PropertyItems;
}
}
// return null;
}
I too found this problem and after modifying the code above, it works fine now.
cheers,
|
|
|
|
|
I have a general question related to RAW image data that i run into when i try to read the EXIF data from an image.
I started out with a free library that uses an System.Drawing.Image as an input and besides the fact that is didn't perform so great with JPG it gave me an "out of memory" exception on the following line:
Image imgImage = Image.FromFile(filePath);
I started using the EXIFExtractor class and get a System.ArgumentException exception on the following line:
Bitmap bmp = new Bitmap(filePath);
I did install the (in my case) CANON RAW codec so i can view them using windows image galary. I thought that the .NET framework would use this codec to open the RAW image, but that was not the case .
Does anybody know how to read/DECODE a RAW image to a .NET Image of Bitmap object?.
|
|
|
|
|