Add your own alternative version
Stats
368.7K views 16.9K downloads 176 bookmarked
Posted
13 Aug 2005

Comments and Discussions



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 />
//5 = RATIONAL Two LONGs. The first LONG is the numerator and the second LONG expresses the//denominator.,<br />
else if( p.Type == 0x5 )<br />
{<br />
I inserted this:
<br />
…<br />
else if( p.Type == 0x5 )<br />
{<br />
//My code starts here<br />
if (p.Id == 0x0004)<br />
{<br />
//lat<br />
// rational<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 />
// Rational r = new Rational(a, b);<br />
}<br />
else if (p.Id == 0x0002)<br />
{<br />
//long<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 />
//My Code ends here<br />
else<br />
{<br />
// rational<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(1Bessel_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(L6) < 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)*(13853111*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));
}







General News Suggestion Question Bug Answer Joke Praise Rant Admin Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

