📄 exifdescriptor.java
字号:
// '4' multi-spot, '5' multi-segment, '6' partial, '255' other
int meteringMode = _directory.getInt(ExifDirectory.TAG_METERING_MODE);
switch (meteringMode) {
case 0:
return "Unknown";
case 1:
return "Average";
case 2:
return "Center weighted average";
case 3:
return "Spot";
case 4:
return "Multi-spot";
case 5:
return "Multi-segment";
case 6:
return "Partial";
case 255:
return "(Other)";
default:
return "";
}
}
public String getSubjectDistanceDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_SUBJECT_DISTANCE)) return null;
Rational distance = _directory.getRational(ExifDirectory.TAG_SUBJECT_DISTANCE);
java.text.DecimalFormat formatter = new DecimalFormat("0.0##");
return formatter.format(distance.doubleValue()) + " metres";
}
public String getCompressionLevelDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_COMPRESSION_LEVEL)) return null;
Rational compressionRatio = _directory.getRational(ExifDirectory.TAG_COMPRESSION_LEVEL);
String ratio = compressionRatio.toSimpleString(_allowDecimalRepresentationOfRationals);
if (compressionRatio.isInteger() && compressionRatio.intValue() == 1) {
return ratio + " bit/pixel";
} else {
return ratio + " bits/pixel";
}
}
public String getThumbnailLengthDescription()
{
if (!_directory.containsTag(ExifDirectory.TAG_THUMBNAIL_LENGTH)) return null;
return _directory.getString(ExifDirectory.TAG_THUMBNAIL_LENGTH) + " bytes";
}
public String getThumbnailOffsetDescription()
{
if (!_directory.containsTag(ExifDirectory.TAG_THUMBNAIL_OFFSET)) return null;
return _directory.getString(ExifDirectory.TAG_THUMBNAIL_OFFSET) + " bytes";
}
public String getYResolutionDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_Y_RESOLUTION)) return null;
Rational resolution = _directory.getRational(ExifDirectory.TAG_Y_RESOLUTION);
return resolution.toSimpleString(_allowDecimalRepresentationOfRationals) +
" dots per " +
getResolutionDescription().toLowerCase();
}
public String getXResolutionDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_X_RESOLUTION)) return null;
Rational resolution = _directory.getRational(ExifDirectory.TAG_X_RESOLUTION);
return resolution.toSimpleString(_allowDecimalRepresentationOfRationals) +
" dots per " +
getResolutionDescription().toLowerCase();
}
public String getExposureTimeDescription()
{
if (!_directory.containsTag(ExifDirectory.TAG_EXPOSURE_TIME)) return null;
return _directory.getString(ExifDirectory.TAG_EXPOSURE_TIME) + " sec";
}
public String getShutterSpeedDescription() throws MetadataException
{
// I believe this method to now be stable, but am leaving some alternative snippets of
// code in here, to assist anyone who's looking into this (given that I don't have a public CVS).
if (!_directory.containsTag(ExifDirectory.TAG_SHUTTER_SPEED)) return null;
// float apexValue = _directory.getFloat(ExifDirectory.TAG_SHUTTER_SPEED);
// int apexPower = (int)Math.pow(2.0, apexValue);
// return "1/" + apexPower + " sec";
// TODO test this method
// thanks to Mark Edwards for spotting and patching a bug in the calculation of this
// description (spotted bug using a Canon EOS 300D)
// thanks also to Gli Blr for spotting this bug
float apexValue = _directory.getFloat(ExifDirectory.TAG_SHUTTER_SPEED);
if (apexValue<=1) {
float apexPower = (float)(1/(Math.exp(apexValue*Math.log(2))));
long apexPower10 = Math.round((double)apexPower * 10.0);
float fApexPower = (float) apexPower10 / 10.0f;
return fApexPower + " sec";
} else {
int apexPower = (int)((Math.exp(apexValue*Math.log(2))));
return "1/" + apexPower + " sec";
}
/*
// This alternative implementation offered by Bill Richards
// TODO determine which is the correct / more-correct implementation
double apexValue = _directory.getDouble(ExifDirectory.TAG_SHUTTER_SPEED);
double apexPower = Math.pow(2.0, apexValue);
StringBuffer sb = new StringBuffer();
if (apexPower > 1)
apexPower = Math.floor(apexPower);
if (apexPower < 1) {
sb.append((int)Math.round(1/apexPower));
} else {
sb.append("1/");
sb.append((int)apexPower);
}
sb.append(" sec");
return sb.toString();
*/
}
public String getFNumberDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_FNUMBER)) return null;
Rational fNumber = _directory.getRational(ExifDirectory.TAG_FNUMBER);
return "F" + SimpleDecimalFormatter.format(fNumber.doubleValue());
}
public String getYCbCrPositioningDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_YCBCR_POSITIONING)) return null;
int yCbCrPosition = _directory.getInt(ExifDirectory.TAG_YCBCR_POSITIONING);
switch (yCbCrPosition) {
case 1: return "Center of pixel array";
case 2: return "Datum point";
default:
return String.valueOf(yCbCrPosition);
}
}
public String getOrientationDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_ORIENTATION)) return null;
int orientation = _directory.getInt(ExifDirectory.TAG_ORIENTATION);
switch (orientation) {
case 1: return "Top, left side (Horizontal / normal)";
case 2: return "Top, right side (Mirror horizontal)";
case 3: return "Bottom, right side (Rotate 180)";
case 4: return "Bottom, left side (Mirror vertical)";
case 5: return "Left side, top (Mirror horizontal and rotate 270 CW)";
case 6: return "Right side, top (Rotate 90 CW)";
case 7: return "Right side, bottom (Mirror horizontal and rotate 90 CW)";
case 8: return "Left side, bottom (Rotate 270 CW)";
default:
return String.valueOf(orientation);
}
}
public String getResolutionDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_RESOLUTION_UNIT)) return "";
// '1' means no-unit, '2' means inch, '3' means centimeter. Default value is '2'(inch)
int resolutionUnit = _directory.getInt(ExifDirectory.TAG_RESOLUTION_UNIT);
switch (resolutionUnit) {
case 1: return "(No unit)";
case 2: return "Inch";
case 3: return "cm";
default:
return "";
}
}
public String getSensingMethodDescription() throws MetadataException
{
if (!_directory.containsTag(ExifDirectory.TAG_SENSING_METHOD)) return null;
// '1' Not defined, '2' One-chip color area sensor, '3' Two-chip color area sensor
// '4' Three-chip color area sensor, '5' Color sequential area sensor
// '7' Trilinear sensor '8' Color sequential linear sensor, 'Other' reserved
int sensingMethod = _directory.getInt(ExifDirectory.TAG_SENSING_METHOD);
switch (sensingMethod) {
case 1:
return "(Not defined)";
case 2:
return "One-chip color area sensor";
case 3:
return "Two-chip color area sensor";
case 4:
return "Three-chip color area sensor";
case 5:
return "Color sequential area sensor";
case 7:
return "Trilinear sensor";
case 8:
return "Color sequential linear sensor";
default:
return "";
}
}
public String getComponentConfigurationDescription() throws MetadataException
{
int[] components = _directory.getIntArray(ExifDirectory.TAG_COMPONENTS_CONFIGURATION);
String[] componentStrings = {"", "Y", "Cb", "Cr", "R", "G", "B"};
StringBuffer componentConfig = new StringBuffer();
for (int i = 0; i < Math.min(4, components.length); i++) {
int j = components[i];
if (j > 0 && j < componentStrings.length) {
componentConfig.append(componentStrings[j]);
}
}
return componentConfig.toString();
}
/**
* Takes a series of 4 bytes from the specified offset, and converts these to a
* well-known version number, where possible. For example, (hex) 30 32 31 30 == 2.10).
* @param components the four version values
* @return the version as a string of form 2.10
*/
public static String convertBytesToVersionString(int[] components)
{
StringBuffer version = new StringBuffer();
for (int i = 0; i < 4 && i < components.length; i++) {
if (i == 2) version.append('.');
String digit = String.valueOf((char)components[i]);
if (i == 0 && "0".equals(digit)) continue;
version.append(digit);
}
return version.toString();
}
/**
* The Windows specific tags uses plain Unicode
*/
private String getUnicodeDescription(int tag) throws MetadataException
{
if (!_directory.containsTag(tag)) return null;
byte[] commentBytes = _directory.getByteArray(tag);
try {
// decode the unicode string
// trim it, as i'm seeing a junk character on the end
return new String(commentBytes, "UTF-16LE").trim();
}
catch (UnsupportedEncodingException ex) {
return null;
}
}
public String getWindowsAuthorDescription() throws MetadataException
{
return getUnicodeDescription(ExifDirectory.TAG_WIN_AUTHOR);
}
public String getWindowsCommentDescription() throws MetadataException
{
return getUnicodeDescription(ExifDirectory.TAG_WIN_COMMENT);
}
public String getWindowsKeywordsDescription() throws MetadataException
{
return getUnicodeDescription(ExifDirectory.TAG_WIN_KEYWORDS);
}
public String getWindowsTitleDescription() throws MetadataException
{
return getUnicodeDescription(ExifDirectory.TAG_WIN_TITLE);
}
public String getWindowsSubjectDescription() throws MetadataException
{
return getUnicodeDescription(ExifDirectory.TAG_WIN_SUBJECT);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -