Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何修复JPG文件中的exif警告和问题?_Android_Exif - Fatal编程技术网

Android 如何修复JPG文件中的exif警告和问题?

Android 如何修复JPG文件中的exif警告和问题?,android,exif,Android,Exif,我写了自己的相机应用程序。此应用程序在jpg文件中写入exif信息。它工作得很好,但exifInferface类存在一些问题,例如,我在重新读取JPG文件时遇到以下错误: Warning Invalid EXIF text encoding Warning Invalid size (8589934590) for IFD0 tag 0x8827 Warning Bad IFD1 directory 我知道exif信息的IFD0指针已断开。可能是在写入exif信息时指针断开了 然而,我在

我写了自己的相机应用程序。此应用程序在jpg文件中写入exif信息。它工作得很好,但exifInferface类存在一些问题,例如,我在重新读取JPG文件时遇到以下错误:

Warning Invalid EXIF text encoding 
Warning Invalid size (8589934590) for IFD0 tag 0x8827 
Warning Bad IFD1 directory 
我知道exif信息的IFD0指针已断开。可能是在写入exif信息时指针断开了

然而,我在谷歌上搜索了一下,什么也没找到

我使用这个类来读写exif信息:

public class ExifHelper {
private String aperature = null;
private String exposureTime = null;
private String flash = null;
private String focalLength = null;
private String gpsAltitude = null;
private String gpsAltitudeRef = null;
private String gpsDateStamp = null;
private String gpsLatitude = null;
private String gpsLatitudeRef = null;
private String gpsLongitude = null;
private String gpsLongitudeRef = null;
private String gpsProcessingMethod = null;
private String gpsTimestamp = null;
private String iso = null;
private String make = null;
private String model = null;
private String imageLength = null;
private String imageWidth = null;
private String orientation = null;
private String whiteBalance = null;  
private String exifVersion = null;
private String time = null;

private ExifInterface inFile = null;
private ExifInterface outFile = null;



final static String TAG = "ExifHelper";
/**
 * The file before it is compressed
 * 
 * @param filePath 
 * @throws IOException
 */
public void createInFile(String filePath) throws IOException {
    this.inFile = new ExifInterface(filePath);       
}

/** 
 * The file after it has been compressed
 * 
 * @param filePath
 * @throws IOException
 */
public void createOutFile(String filePath) throws IOException {
    this.outFile = new ExifInterface(filePath);
}

/**
 * Reads all the EXIF data from the input file.
 */
public void readExifData() {
    this.aperature = inFile.getAttribute(ExifInterface.TAG_APERTURE);
    this.exposureTime = inFile.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
    this.flash = inFile.getAttribute(ExifInterface.TAG_FLASH);
    this.focalLength = inFile.getAttribute(ExifInterface.TAG_FOCAL_LENGTH);
    this.gpsAltitude = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE);
    this.gpsAltitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF);
    this.gpsDateStamp = inFile.getAttribute(ExifInterface.TAG_GPS_DATESTAMP);
    this.gpsLatitude = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
    this.gpsLatitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
    this.gpsLongitude = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
    this.gpsLongitudeRef = inFile.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
    this.gpsProcessingMethod = inFile.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD);
    this.gpsTimestamp = inFile.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP);
    this.imageLength = inFile.getAttribute(ExifInterface.TAG_IMAGE_LENGTH);
    this.imageWidth = inFile.getAttribute(ExifInterface.TAG_IMAGE_WIDTH);
    this.iso = inFile.getAttribute(ExifInterface.TAG_ISO);
    this.make = inFile.getAttribute(ExifInterface.TAG_MAKE);
    this.model = inFile.getAttribute(ExifInterface.TAG_MODEL);
    this.orientation = inFile.getAttribute(ExifInterface.TAG_ORIENTATION);
    this.whiteBalance = inFile.getAttribute(ExifInterface.TAG_WHITE_BALANCE);  
    this.exifVersion = inFile.getAttribute("ExifVersion");
}

/**
 * Writes the previously stored EXIF data to the output file. 
 * @param pictureDate 
 * @param orientationValues 
 * @param accelValues 
 * 
 * @throws IOException
 */
public void writeExifData(String pictureDate) throws IOException {
    // Don't try to write to a null file
    if (this.outFile == null) {
        return;
    }

    if (this.aperature != null) {
        this.outFile.setAttribute(ExifInterface.TAG_APERTURE, this.aperature);
    }
    if (this.exposureTime != null) {
        this.outFile.setAttribute(ExifInterface.TAG_EXPOSURE_TIME, this.exposureTime);
    }
    if (this.flash != null) {
        this.outFile.setAttribute(ExifInterface.TAG_FLASH, this.flash);
    }
    if (this.focalLength != null) {
        this.outFile.setAttribute(ExifInterface.TAG_FOCAL_LENGTH, this.focalLength);
    }
    if (this.gpsAltitude != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE, this.gpsAltitude);
    }
    if (this.gpsAltitudeRef != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_ALTITUDE_REF, this.gpsAltitudeRef);
    }
    if (this.gpsDateStamp != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_DATESTAMP, this.gpsDateStamp);
    }
    if (this.gpsLatitude != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE, this.gpsLatitude);
    }
    if (this.gpsLatitudeRef != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, this.gpsLatitudeRef);
    }
    if (this.gpsLongitude != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, this.gpsLongitude);
    }
    if (this.gpsLongitudeRef != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, this.gpsLongitudeRef);
    }
    if (this.gpsProcessingMethod != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD, this.gpsProcessingMethod);
    }
    if (this.gpsTimestamp != null) {
        this.outFile.setAttribute(ExifInterface.TAG_GPS_TIMESTAMP, this.gpsTimestamp);
    }
    if (this.iso != null) {
        this.outFile.setAttribute(ExifInterface.TAG_ISO, this.iso);
    }
    if (this.make != null) {
        this.outFile.setAttribute(ExifInterface.TAG_MAKE, this.make);
    }
    if (this.model != null) {
        this.outFile.setAttribute(ExifInterface.TAG_MODEL, this.model);
    }
    if (this.orientation != null) {
        this.outFile.setAttribute(ExifInterface.TAG_ORIENTATION, this.orientation);
    }
    if (this.whiteBalance != null) {
        this.outFile.setAttribute(ExifInterface.TAG_WHITE_BALANCE, this.whiteBalance);
    }
    if (this.exifVersion != null) {
        this.outFile.setAttribute("ExifVersion", this.exifVersion);
    }


    this.outFile.setAttribute(ExifInterface.TAG_IMAGE_LENGTH, this.imageLength);    
    this.outFile.setAttribute(ExifInterface.TAG_IMAGE_WIDTH, this.imageWidth);
    this.outFile.setAttribute(ExifInterface.TAG_DATETIME, pictureDate);
    String mString = exifRandomZahlen();
    this.outFile.setAttribute("UserComment", mString);

    this.outFile.saveAttributes();
}
我还写了两张照片,形成了拍摄方法。一个是原来没有问题,第二个是修改exif信息。我认为,通过将ExiFinInterface写回JPG,它存在问题

我使用DumpImage工具查看exif信息。此工具来自元工作组www.metadataworkinggroup.org

所以我有一个大问题,如何修复这个损坏的exif数据?例如,IDF0指针 有人知道或有同样的问题吗

例如,我在exif信息中两次获得Tag_DATETIME

这是用于保存照片的类:

public class Photo extends Activity implements PictureCallback {
public interface OnPictureTakenListener {
    void pictureTaken(File pictureFile, File pictureFilePatched, String exifDateString);
}

private final Context context;
private OnPictureTakenListener listener;

public Photo(Context ourContext, OnPictureTakenListener theListener) {
    this.context = ourContext;
    this.listener = theListener;
}

@SuppressLint("SimpleDateFormat")
@Override
public void onPictureTaken(byte[] data, Camera camera) {

    Date date = new Date();

    File pictureFileDir = getDir();

    if (!pictureFileDir.exists() && !pictureFileDir.mkdirs())

    {
        Log.d(AndroidCamera.DEBUG_TAG,
                "Can't create directory to save image.");
        Toast.makeText(context, "Can't create directory to save image.",
                Toast.LENGTH_LONG).show();
        return;
    }

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
    SimpleDateFormat dateConverter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");

    String exifDateString = dateFormat.format(date);

    String datePicture = dateConverter.format(date); 

    String photoFile = "Picture_" + datePicture + ".jpg";

    String photoFilePatched = "Picture_" + datePicture + "_patched.jpg";

    String filename = pictureFileDir.getPath() + File.separator + photoFile;

    String filenamePatched =  pictureFileDir.getPath() + File.separator + photoFilePatched;

    File pictureFile = new File(filename);

    File pictureFilePatched = new File (filenamePatched);

    try {
        FileOutputStream fos = new FileOutputStream(pictureFile);
        FileOutputStream fosPatched = new FileOutputStream(pictureFilePatched);
        fos.write(data);
        fosPatched.write(data);
        fos.close();
        fosPatched.close();



        Toast.makeText(context, "New Image saved:" + photoFile,
                Toast.LENGTH_LONG).show();
    } catch (Exception error) {
        Log.d(AndroidCamera.DEBUG_TAG, "File" + filename + " not saved: "
                + error.getMessage());
        Toast.makeText(context, "Image could not be saved.",
                Toast.LENGTH_LONG).show();
    }

    listener.pictureTaken(pictureFile,pictureFilePatched,exifDateString);
    context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

}


private File getDir() {
    File sdDir = Environment
            .getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
    return new File(sdDir, "Camera");
}

static final int REQUEST_IMAGE_CAPTURE = 1;
}

在这里的主要活动中,我从两张图片中调用一张来编写exif信息:

camera.takePicture(null, null, new Photo(this,
            new Photo.OnPictureTakenListener() {
                public void pictureTaken(final File pictureFile,final File pictureFilePatched , final String date) {

                    final String fileName = pictureFile.getPath();
                    final String fileNamePatched = pictureFilePatched.getPath();
                    final String dateTime = date;
                    // don't start picture preview immediately, but a little
                    // delayed...
                    continueWithPreview.postDelayed(new Runnable() {

                        @Override
                        public void run() {

                                try {
                                // EXIF Matadata change
                                    ExifHelper exifHelper = new ExifHelper();
                                    exifHelper.createInFile(fileName);
                                    //EXIF Metadata read
                                    exifHelper.readExifData();
                                    exifHelper.createOutFile(fileNamePatched);  
                                    //Exif Metadata write
                                    exifHelper.writeExifData(dateTime);


                            } catch (IOException e) {
                                e.printStackTrace();
                                Log.e("PictureActivity", e.getLocalizedMessage());
                            } 

                            if (null != camera)
                            {
                                camera.startPreview();
                                Toast.makeText(AndroidCamera.this, "started!",
                                        Toast.LENGTH_SHORT).show();
                            }

                        }
                    }, 2500);

请说明如何在文件上调用此类的函数。还是在两个文件上?我已经更新了我的图片?那是一个应用程序吗?不是在游戏商店。我做了一个活动,把你的ExifHelper放进去,拿了一个jpg文件并复制了一份。然后执行try块中的五条语句。修补后的图像可以显示,但由于我没有应用程序调查exif,我将文件传输到了PC顶部。使用IrfanView查看ExifInfo。原始文件有43个exif标记,修补的只有19个。您正在从一个文件中读取exif信息,然后通过对另一个文件的一些更改将此信息写回。你为什么不从文件本身读取它呢?你有没有做过一个测试,从一个文件中读取exif信息,然后将其原封不动地写回同一个文件?我会再写更多exif标签回来。。。但是ExiFinInterface类不会将其添加到其他类中,因为它会覆盖exif信息。因此,只有exifhelper类中的exif标记才会添加到exif元数据中