Пример #1
0
static struct LatLon get_latlon ( ExifData *ed )
{
	struct LatLon ll = { 0.0, 0.0 };
	const struct LatLon ll0 = { 0.0, 0.0 };

	gchar str[128];
	ExifEntry *ee;
	//
	// Lat & Long is necessary to form a waypoint.
	//
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE);
	if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		return ll0;

	ll.lat = Rational2Double ( ee->data,
							   exif_format_get_size(ee->format),
							   exif_data_get_byte_order(ed) );

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE_REF);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( str[0] == 'S' )
			ll.lat = -ll.lat;
	}

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE);
	if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		return ll0;

	ll.lon = Rational2Double ( ee->data,
							   exif_format_get_size(ee->format),
							   exif_data_get_byte_order(ed) );

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE_REF);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( str[0] == 'W' )
			ll.lon = -ll.lon;
	}

	return ll;
}
Пример #2
0
LocImageContainer ImageProcessor::process (QString filename)
{
	QImage image (m_data);

	if (!image.isNull()) {
		image = image.scaled(720, 500, Qt::KeepAspectRatioByExpanding);
	}

	LocImageContainer locImageContainer(image);

	locImageContainer.setAltitude(3000.00);

	//get exif data
	ExifData *ed = exif_data_new_from_file (filename.toLocal8Bit().constData());

	if (!ed) {
		locImageContainer.setLocationAvailable(false);
		locImageContainer.setExifDataAvailable(false);

		return locImageContainer;
	}

	locImageContainer.setExifDataAvailable(true);

	//save temp
	char value[256]={0,};

	// Retrieve make
	QString make;
	ExifEntry *ee = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
	if (!ee) {
		make = "";
	} else {
		exif_entry_get_value(ee, value, sizeof(value));
		locImageContainer.setMake (QString(value));
	}

	// Retrieve model
	ee = exif_content_get_entry(ed->ifd[EXIF_IFD_0], EXIF_TAG_MODEL);
	if (!ee) {
		locImageContainer.setCameraModel ("");
	} else {
		exif_entry_get_value(ee, value, sizeof(value));
		locImageContainer.setCameraModel ("Taken with the "+QString(value));
	}

	// Retrieve time
	ee = exif_content_get_entry(ed->ifd[EXIF_IFD_EXIF], EXIF_TAG_DATE_TIME_ORIGINAL);
	if (!ee) {
		locImageContainer.setDateTaken ("");
	} else {
		exif_entry_get_value(ee, value, sizeof(value));
		QString dateTime(value);

		QDateTime dateTaken = QDateTime::fromString (dateTime, "yyyy:MM:dd HH:mm:ss");
		locImageContainer.setDateTaken (dateTaken.toString("'on 'dddd d, MMMM yyyy 'at' HH:mm"));
	}

	// Retrieve LATITUDE
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], (ExifTag)EXIF_TAG_GPS_LATITUDE);
	if (!ee) {
		locImageContainer.setLocationAvailable(false);
		locImageContainer.setLatitude(-9999.99);
	} else {
		if ( ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		{
			double lat = Rational2Double ( ee->data,
					exif_format_get_size(ee->format),
					exif_data_get_byte_order(ed) );

			ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], (ExifTag)EXIF_TAG_GPS_LATITUDE_REF);
			if ( ee ) {
				exif_entry_get_value ( ee, value, 128 );
				if ( value[0] == 'S' )
					lat = -lat;
			}

			locImageContainer.setLocationAvailable(true);
			locImageContainer.setLatitude (lat);
		}
	}

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], (ExifTag)EXIF_TAG_GPS_LONGITUDE);
	if (!ee) {
		locImageContainer.setLocationAvailable(false);
		locImageContainer.setLongitude(-9999.99);
	} else {
		if ( ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		{
			double lon = Rational2Double ( ee->data,
					exif_format_get_size(ee->format),
					exif_data_get_byte_order(ed) );

			ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], (ExifTag)EXIF_TAG_GPS_LONGITUDE_REF);
			if ( ee ) {
				exif_entry_get_value ( ee, value, 128 );
				if ( value[0] == 'W' )
					lon = -lon;
			}

			locImageContainer.setLocationAvailable(true);
			locImageContainer.setLongitude (lon);
		}
	}

	exif_data_free(ed);

	return locImageContainer;
}
Пример #3
0
/**
 * a_geotag_create_waypoint_from_file:
 * @filename: The image file to process
 * @vcmode:   The current location mode to use in the positioning of Waypoint
 * @name:     Returns a name for the Waypoint (can be NULL)
 *
 * Returns: An allocated Waypoint or NULL if Waypoint could not be generated (e.g. no EXIF info)
 *
 */
VikWaypoint* a_geotag_create_waypoint_from_file ( const gchar *filename, VikCoordMode vcmode, gchar **name )
{
	// Default return values (for failures)
	*name = NULL;
	VikWaypoint *wp = NULL;

	// TODO use log?
	//ExifLog *log = NULL;

	// open image with libexif
	ExifData *ed = exif_data_new_from_file ( filename );

	// Detect EXIF load failure
	if ( !ed )
		// return with no Waypoint
		return wp;

	struct LatLon ll;

	gchar str[128];
	ExifEntry *ee;

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID);
	// Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0"
	if ( ! ( ee && ee->components == 4 ) )
		goto MyReturn;
	// Could test for these versions explicitly but may have byte order issues...
	//if ( ! ( ee->data[0] == 2 && ee->data[2] == 0 && ee->data[3] == 0 ) )
	//	goto MyReturn;


	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_MAP_DATUM);
	if ( ! ( ee && ee->components > 0 && ee->format == EXIF_FORMAT_ASCII ) )
		goto MyReturn;

	// If map datum specified - only deal in WGS-84 - the defacto standard
	if ( ee && ee->components > 0 ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( strncmp (str, "WGS-84", 6) )
			goto MyReturn;
	}

	//
	// Lat & Long is necessary to form a waypoint.
	//
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE);
	if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		goto MyReturn;
  
	ll.lat = Rational2Double ( ee->data,
							   exif_format_get_size(ee->format),
							   exif_data_get_byte_order(ed) );

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LATITUDE_REF);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( str[0] == 'S' )
			ll.lat = -ll.lat;
	}

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE);
	if ( ! ( ee && ee->components == 3 && ee->format == EXIF_FORMAT_RATIONAL ) )
		goto MyReturn;

	ll.lon = Rational2Double ( ee->data,
							   exif_format_get_size(ee->format),
							   exif_data_get_byte_order(ed) );

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_LONGITUDE_REF);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		if ( str[0] == 'W' )
			ll.lon = -ll.lon;
	}

	//
	// Not worried if none of the other fields exist, as can default the values to something
	//

	gdouble alt = VIK_DEFAULT_ALTITUDE;
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE);
	if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_RATIONAL ) {
		alt = Rational2Double ( ee->data,
								0,
								exif_data_get_byte_order(ed) );

		ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE_REF);
		if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_BYTE && ee->data[0] == 1 )
			alt = -alt;
	}

	// Name
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		*name = g_strdup ( str );
	}

	//
	// Now create Waypoint with acquired information
	//
	wp = vik_waypoint_new();
	wp->visible = TRUE;
	// Set info from exif values
	// Location
	vik_coord_load_from_latlon ( &(wp->coord), vcmode, &ll );
	// Altitude
	wp->altitude = alt;

	wp->comment = geotag_get_exif_comment ( ed );

	vik_waypoint_set_image ( wp, filename );

MyReturn:
	// Finished with EXIF
	exif_data_free ( ed );

	return wp;
}
Пример #4
0
/**
 * a_geotag_create_waypoint_from_file:
 * @filename: The image file to process
 * @vcmode:   The current location mode to use in the positioning of Waypoint
 * @name:     Returns a name for the Waypoint (can be NULL)
 *
 * Returns: An allocated Waypoint or NULL if Waypoint could not be generated (e.g. no EXIF info)
 *
 */
VikWaypoint* a_geotag_create_waypoint_from_file ( const gchar *filename, VikCoordMode vcmode, gchar **name )
{
	// Default return values (for failures)
	*name = NULL;
	VikWaypoint *wp = NULL;

#ifdef HAVE_LIBGEXIV2
	GExiv2Metadata *gemd = gexiv2_metadata_new ();
	if ( gexiv2_metadata_open_path ( gemd, filename, NULL ) ) {
		gdouble lat;
		gdouble lon;
		gdouble alt;
		if ( gexiv2_metadata_get_gps_info ( gemd, &lon, &lat, &alt ) ) {
			struct LatLon ll;
			ll.lat = lat;
			ll.lon = lon;

			//
			// Now create Waypoint with acquired information
			//
			wp = vik_waypoint_new();
			wp->visible = TRUE;
			// Set info from exif values
			// Location
			vik_coord_load_from_latlon ( &(wp->coord), vcmode, &ll );
			// Altitude
			wp->altitude = alt;

			if ( gexiv2_metadata_has_tag ( gemd, "Exif.Image.XPTitle" ) )
				*name = g_strdup ( gexiv2_metadata_get_tag_interpreted_string ( gemd, "Exif.Image.XPTitle" ) );
			wp->comment = geotag_get_exif_comment ( gemd );

			// Direction
			VikWaypointImageDirectionRef ref = WP_IMAGE_DIRECTION_REF_TRUE;
			if ( gexiv2_metadata_has_tag ( gemd, EXIF_GPS_IMGDIR_REF ) ) {
				gchar* ref_str = gexiv2_metadata_get_tag_interpreted_string(gemd, EXIF_GPS_IMGDIR_REF);
				if ( ref_str && g_ascii_strncasecmp ("M", ref_str, 1) == 0 )
					ref = WP_IMAGE_DIRECTION_REF_MAGNETIC;
				g_free ( ref_str );
			}
			if ( gexiv2_metadata_has_tag ( gemd, EXIF_GPS_IMGDIR ) ) {
				gint nom;
				gint den;
				gdouble direction = NAN;
				if ( gexiv2_metadata_get_exif_tag_rational (gemd, EXIF_GPS_IMGDIR, &nom, &den) )
					if ( den != 0 )
						direction = (gdouble)nom/(gdouble)den;

				if ( !isnan(direction) )
					vik_waypoint_set_image_direction_info ( wp, direction, ref );
			}

			vik_waypoint_set_image ( wp, filename );
		}
	}
	metadata_free ( gemd );
#else
#ifdef HAVE_LIBEXIF
	// TODO use log?
	//ExifLog *log = NULL;

	// open image with libexif
	ExifData *ed = exif_data_new_from_file ( filename );

	// Detect EXIF load failure
	if ( !ed )
		// return with no Waypoint
		return wp;

	struct LatLon ll;

	gchar str[128];
	ExifEntry *ee;

	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_VERSION_ID);
	// Confirm this has a GPS Id - normally "2.0.0.0" or "2.2.0.0"
	if ( ! ( ee && ee->components == 4 ) )
		goto MyReturn;
	// Could test for these versions explicitly but may have byte order issues...
	//if ( ! ( ee->data[0] == 2 && ee->data[2] == 0 && ee->data[3] == 0 ) )
	//	goto MyReturn;

	ll = get_latlon ( ed );

	// Hopefully won't have valid images at 0,0!
	if ( ll.lat == 0.0 && ll.lon == 0.0 )
		goto MyReturn;

	//
	// Not worried if none of the other fields exist, as can default the values to something
	//

	gdouble alt = VIK_DEFAULT_ALTITUDE;
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE);
	if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_RATIONAL ) {
		alt = Rational2Double ( ee->data,
								0,
								exif_data_get_byte_order(ed) );

		ee = exif_content_get_entry (ed->ifd[EXIF_IFD_GPS], EXIF_TAG_GPS_ALTITUDE_REF);
		if ( ee && ee->components == 1 && ee->format == EXIF_FORMAT_BYTE && ee->data[0] == 1 )
			alt = -alt;
	}

	// Name
	ee = exif_content_get_entry (ed->ifd[EXIF_IFD_0], EXIF_TAG_XP_TITLE);
	if ( ee ) {
		exif_entry_get_value ( ee, str, 128 );
		*name = g_strdup ( str );
	}

	//
	// Now create Waypoint with acquired information
	//
	wp = vik_waypoint_new();
	wp->visible = TRUE;
	// Set info from exif values
	// Location
	vik_coord_load_from_latlon ( &(wp->coord), vcmode, &ll );
	// Altitude
	wp->altitude = alt;

	wp->comment = geotag_get_exif_comment ( ed );

	vik_waypoint_set_image ( wp, filename );

MyReturn:
	// Finished with EXIF
	exif_data_free ( ed );
#endif
#endif

	return wp;
}