Commit 9b0ad10d authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Tiff writer, fixed bug in Z interpolation in plane render

parent beaa0851
Loading
Loading
Loading
Loading
+8 −5
Original line number Diff line number Diff line
@@ -481,6 +481,7 @@ public class CLTParameters {
	public double     gmap_discard_rdisp =   0.02;  // discard above/below this fraction of average height
	public double     gmap_pix_size =        0.005; // hdr_x0y0,       // in meters
	public int        gmap_max_image_width = 4000;  // 3200;  // increase pixel size as a power of 2 until image fits
	public double     gmap_min_sfm =         10.0;  // minimal SfM gain to keep ground map
	public boolean    gmap_crop_empty =      true;
	public int        gmap_crop_extra =      20;
	public int []     gmap_tex_pals =        {0,1,2};
@@ -1626,6 +1627,7 @@ public class CLTParameters {
		properties.setProperty(prefix+"gmap_discard_rdisp",         this.gmap_discard_rdisp+"");         // double
		properties.setProperty(prefix+"gmap_pix_size",              this.gmap_pix_size+"");              // double
		properties.setProperty(prefix+"gmap_max_image_width",       this.gmap_max_image_width+"");       // int     
		properties.setProperty(prefix+"gmap_min_sfm",               this.gmap_min_sfm+"");               // double
		properties.setProperty(prefix+"gmap_crop_empty",            this.gmap_crop_empty+"");            // boolean 
		properties.setProperty(prefix+"gmap_crop_extra",            this.gmap_crop_extra+"");            // int     
		properties.setProperty(prefix+"gmap_tex_pals",              CLTParameters.arr_to_str(this.gmap_tex_pals)); // int[]
@@ -2644,6 +2646,7 @@ public class CLTParameters {
		if (properties.getProperty(prefix+"gmap_discard_rdisp")!=null)   this.gmap_discard_rdisp=Double.parseDouble(properties.getProperty(prefix+  "gmap_discard_rdisp"));
		if (properties.getProperty(prefix+"gmap_pix_size")!=null)        this.gmap_pix_size=Double.parseDouble(properties.getProperty(prefix+       "gmap_pix_size"));
		if (properties.getProperty(prefix+"gmap_max_image_width")!=null) this.gmap_max_image_width=Integer.parseInt(properties.getProperty(prefix+  "gmap_max_image_width"));
		if (properties.getProperty(prefix+"gmap_min_sfm")!=null)         this.gmap_min_sfm=Double.parseDouble(properties.getProperty(prefix+       "gmap_min_sfm"));
   		if (properties.getProperty(prefix+"gmap_crop_empty")!=null)      this.gmap_crop_empty=Boolean.parseBoolean(properties.getProperty(prefix+   "gmap_crop_empty"));
		if (properties.getProperty(prefix+"gmap_crop_extra")!=null)      this.gmap_crop_extra=Integer.parseInt(properties.getProperty(prefix+       "gmap_crop_extra"));// int     
		if (properties.getProperty(prefix+"gmap_tex_pals")!=null)        this.gmap_tex_pals=CLTParameters.str_to_iarr(properties.getProperty(prefix+"gmap_tex_pals"));
@@ -3908,6 +3911,8 @@ public class CLTParameters {
				"Rendered absolute pixel size in meters.");
		gd.addNumericField("Maximal rendered image width",         this.gmap_max_image_width, 0,3,"",
				"Maximal output image size in pixels. Increase pixel size in the power-of-two ratio if calculated image width exceeds this value.");
		gd.addNumericField("Minimal SfM gain",                     this.gmap_min_sfm,  4,6,"x",
				"Minimal SfM gain to keep ground map, lower makes texture transparent.");
		gd.addCheckbox ("Crop empty map areas",                    this.gmap_crop_empty, // true; // enable change FG pixel to opaque from transparent
				"Crop the map output from four directions while only undefined pixels are removed.");
		gd.addNumericField("Crop maps extra",                      this.gmap_crop_extra, 0,3,"pix",  // minimal neighbors to keep alpha
@@ -3915,7 +3920,6 @@ public class CLTParameters {
		gd.addStringField ("LWIR palettes to render the maps",     CLTParameters.arr_to_str(this.gmap_tex_pals), 40,
				"Enter space-separated list of the palette numbers, such as, such as '0 1 2'");
		
		
		gd.addMessage     ("Earlier 3D generation parameters");
		gd.addCheckbox    ("Generate background (infinity) image for 3D (not needed for view down)",                 this.generate_bg);
		gd.addCheckbox    ("Show generated textures",                                                                this.show_textures);
@@ -5125,13 +5129,12 @@ public class CLTParameters {
		this.gmap_discard_high=     gd.getNextNumber();
		this.gmap_discard_adisp=    gd.getNextNumber();
		this.gmap_discard_rdisp=    gd.getNextNumber();
		gmap_pix_size=              gd.getNextNumber();
		this.gmap_pix_size=         gd.getNextNumber();
		this.gmap_max_image_width= (int) gd.getNextNumber();
		this.gmap_min_sfm=          gd.getNextNumber();
		this.gmap_crop_empty=       gd.getNextBoolean();
		this.gmap_crop_extra= (int) gd.getNextNumber();
		
		this.gmap_tex_pals =           CLTParameters.str_to_iarr(gd.getNextString());
		
		this.generate_bg=           gd.getNextBoolean();
		this.show_textures=         gd.getNextBoolean();
		this.debug_filters=         gd.getNextBoolean();
+98 −311
Original line number Diff line number Diff line
@@ -70,113 +70,41 @@ public class ElphelTiffWriter {
	
	public static void saveTiffARGB32(
			ImagePlus     imp,
			String path,
			boolean imageJTags,
			String        path, // full path to save image
			double []     lla,  // latitude, longitude, altitude (or null)
			LocalDateTime dt,   // local date/time or null
			double        pix_in_meters, // resolution or Double.NaN
			boolean       imageJTags, // later will use it to encode from properties
			int           debugLevel
			) {
//		ImageWriter     tiffWriter;
//	    ImageWriteParam tiffWriteParam;
	    IIOMetadata     tiffStreamMetadata;
	    IIOMetadata     primaryIFD;
	    BufferedImage   bufferedImage = (BufferedImage) imp.getImage(); // properties=null
	    BufferedImage   thumbnail;		
	    File outputFile = new File(path);
	    if (debugLevel > 0) {
	    	System.out.println("saveTiffARGB32(): will write to "+outputFile);
	    	System.out.println("ElphelTiffWriter.saveTiffARGB32");
	       // Write only the primary IFD and image data.
	    // Specify uncompressed output.
	    }
	    ImageWriter tiffWriter = ImageIO.getImageWritersByFormatName("tiff").next();
	    ImageWriteParam tiffWriteParam = tiffWriter.getDefaultWriteParam();
//	    tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
// https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/imageio/metadata/doc-files/tiff_metadata.html	    
//	    tiffWriteParam.setCompressionType("Exif JPEG");
	    tiffWriteParam.setCompressionMode(ImageWriteParam.MODE_DISABLED);
//	    tiffWriteParam.setSourceSubsampling(param.getSourceXSubsampling(), param.getSourceYSubsampling(), param.getSubsamplingXOffset(), param.getSubsamplingYOffset());
//	    tiffWriteParam.setSourceRegion(param.getSourceRegion());
//	    tiffWriteParam.setSourceBands(param.getSourceBands());
/*
 * https://docs.oracle.com/javase%2F9%2Fdocs%2Fapi%2F%2F/javax/imageio/metadata/doc-files/tiff_metadata.html
    Setting up the image metadata to write to a TIFF stream may be simplified by using
    the TIFFDirectory class which represents a TIFF IFD. A field in a TIFF IFD is represented
    by an instance of TIFFField. For each field to be written a TIFFField may be added to
    the TIFFDirectory and the latter converted to an IIOMetadata object by invoking
    TIFFDirectory.getAsMetadata. The IIOMetadata object so obtained may then be passed to
    the TIFF writer.
    
ImageTypeSpecifier
ImageTypeSpecifier(ColorModel colorModel, SampleModel sampleModel)
Constructs an ImageTypeSpecifier directly from a ColorModel and a SampleModel.
    
static long computeImageSize(RenderedImage image) {
  long bits = 0;
  final int bands = image.getSampleModel().getNumBands();
  for (int i = 0; i < bands; i++) {
    bits += image.getSampleModel().getSampleSize(i);
  }
  return (long) Math.ceil(bits / 8) * image.getWidth() * image.getHeight();
}

void 	setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)
Sets an array of integer pixels in the default RGB color model (TYPE_INT_ARGB) and default sRGB color space, into a portion of the image data.
    
 */
//	    Raster 	raster = bufferedImage.getData(); // use pixels from IJ
	    /* ImagePlus image removes alpha, so we need to create a new ARGB BufferedImage
	     * and copy data (it is correct in imp.getImage() */
	    BufferedImage   bufferedImage = (BufferedImage) imp.getImage(); // properties=null
	    BufferedImage bufferedImageAlpha = new BufferedImage(
	    		bufferedImage.getWidth(),
	    		bufferedImage.getHeight(),
	    		BufferedImage.TYPE_INT_ARGB
	    		);
	    		BufferedImage.TYPE_INT_ARGB);
	    int [] ipixels = (int[])imp.getProcessor().getPixels();
	    final int[] bia_as_arr = ( (DataBufferInt) bufferedImageAlpha.getRaster().getDataBuffer() ).getData();
	    System.arraycopy(ipixels, 0, bia_as_arr, 0, bia_as_arr.length);
	    /*
	    bufferedImageAlpha.setRGB( // slow
	    		0,                         // int startX,
	    		0,                         // int startY,
	    		bufferedImage.getWidth(),  // int w,
	    		bufferedImage.getHeight(), // int h,
	    		ipixels,                   // int[] rgbArray,
	    		0,                         // int offset,
	    		bufferedImage.getWidth()); // int scansize);
	    */
	    
	    
	    
//	    bufferedImageAlpha.setData(raster);
	    //BufferedImage.TYPE_INT_ARGB
//	    ColorModel colorModel = ColorModel.getRGBdefault();
//	    SampleModel samleModel = bufferedImage.getSampleModel();
//	    ImageTypeSpecifier imageType = ImageTypeSpecifier.createFromRenderedImage(bufferedImage);            
	    ImageTypeSpecifier imageType = ImageTypeSpecifier.createFromRenderedImage(bufferedImageAlpha);            
	    IIOMetadata imageMetadata = tiffWriter.getDefaultImageMetadata(imageType, tiffWriteParam);
// just for testing:
	    double [] lla = {	49.9476514222895,28.5547846609957,323.750316821841};
	    LocalDateTime dt =  Did_ins.getLocalDateTime(2286, 491072.634526699);
	    double pix_in_meters = 0.01;
	    int cm_dig_after = 9;
	    // Here is a way adding tag sets through TIFFDirectory
	    /*
	    ExifGPSTagSet exif_tag_set = ExifGPSTagSet.getInstance();
	    
	    
	    TIFFTagSet [] tag_sets = {ExifGPSTagSet.getInstance()} ;
	    ExifParentTIFFTagSet eptts = ExifParentTIFFTagSet.getInstance();
	    TIFFDirectory gps_directory = new TIFFDirectory(
	    		tag_sets, eptts.getTag(
				ExifParentTIFFTagSet.TAG_GPS_INFO_IFD_POINTER));
	    
	    TIFFTagSet tag_set = ExifGPSTagSet.getInstance();
	    TIFFField gps_ifd = null;
//	    int df = TIFFField.TIFF_IFD_POINTER; // 13
	    gps_ifd = new TIFFField(
	    		eptts.getTag(
	    				ExifParentTIFFTagSet.TAG_GPS_INFO_IFD_POINTER), // 'ExifIFDPointer', // TIFFTag tag,
	    		13,            // TIFFField.TIFF_IFD_POINTER, // int type,
	    		(long)         0, // long offset,
	    		(TIFFDirectory) gps_directory); // TIFFDirectory dir)
	    directory.addTIFFField(gps_ifd);
	    directory.addTagSet(tag_set); // ExifGPSTagSet.getInstance());
	    
	    */
	    
	    /* */
	    TIFFDirectory directory = null;
	    try {
			directory = TIFFDirectory.createFromMetadata(imageMetadata);
@@ -191,122 +119,41 @@ Sets an array of integer pixels in the default RGB color model (TYPE_INT_ARGB) a
	    directory.addTagSet(eptts);   // ExifParentTIFFTagSet.getInstance());
	    //ExifGPSTagSet
	    imageMetadata = directory.getAsMetadata();
	    /* */
	    */
	    
	    IIOMetadataNode root_new = (IIOMetadataNode) imageMetadata.getAsTree(TIFF_METADATA_FORMAT);//?
	    
	    System.out.println("\n=== root_new ===:");
	    DumpImageMetadata.displayMetadataNode(root_new, 1);
	    
//	    createGpsMetadata(double [] lla, LocalDateTime dt)
	    
	    
	    if (debugLevel > 0) {System.out.println("\n=== root_new ===:");DumpImageMetadata.displayMetadataNode(root_new, 1);}
	    IIOMetadataNode ifd =    (IIOMetadataNode)  root_new.getFirstChild();
	    String ifd_attr =        ifd.getAttribute("tagSets");
	    // set it to ifd_attr	"javax.imageio.plugins.tiff.BaselineTIFFTagSet,javax.imageio.plugins.tiff.ExifGPSTagSet,javax.imageio.plugins.tiff.ExifParentTIFFTagSet" (id=187)
	    // remove directory above and addTagSet
	    ifd.setAttribute("tagSets",
	    		"javax.imageio.plugins.tiff.BaselineTIFFTagSet,javax.imageio.plugins.tiff.ExifGPSTagSet,javax.imageio.plugins.tiff.ExifParentTIFFTagSet");
	    if ((lla != null) || (dt!=null)) { 
	    	IIOMetadataNode gpsRootNode = createGpsMetadata(lla, dt);
	    /*
	    IIOMetadataNode gpsRootNode = new IIOMetadataNode("TIFFIFD");
	    gpsRootNode.setAttribute("parentTagNumber", "34853");
	    gpsRootNode.setAttribute("parentTagName",   "GPSInfoIFDPointer");
	    gpsRootNode.setAttribute("tagSets", "javax.imageio.plugins.tiff.ExifGPSTagSet");

	    IIOMetadataNode childNode = new IIOMetadataNode(TIFF_FIELD_TAG);
	    childNode.setAttribute("number", "1");
	    childNode.setAttribute("name", "GPSLatitudeRef");
	    IIOMetadataNode asciiNode = new IIOMetadataNode(TIFF_ASCIIS_TAG);
	    IIOMetadataNode childAsciiNode = new IIOMetadataNode(TIFF_ASCII_TAG);
	    childAsciiNode.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, "N");
	    asciiNode.appendChild(childAsciiNode);
	    childNode.appendChild(asciiNode);
	    gpsRootNode.appendChild(childNode);
	    */
	    System.out.println("\n=== gpsRootNode ===:");
	    DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
	    
	    
	    addResolutionMetadata(ifd,pix_in_meters,cm_dig_after);
	    	if (debugLevel > 0) {System.out.println("\n=== gpsRootNode ===:");DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);}
	    	ifd.appendChild(gpsRootNode);
	    }
	    addResolutionMetadata(ifd,pix_in_meters,cm_dig_after); // NOP if pix_in_meters is NaN 
	    
	    System.out.println("\n=== ifd ===:");
	    DumpImageMetadata.displayMetadataNode(ifd, 1);

	    /*
IIOMetadataNode childNode = new IIOMetadataNode(FileConstants.TIFF_FIELD_TAG);
childNode.setAttribute(FileConstants.TIFF_FIELD_NUMBER_ATTRIBUTE, "1");
childNode.setAttribute(FileConstants.TIFF_FIELD_NAME_ATTRIBUTE, "GPSLatitudeRef");
IIOMetadataNode asciiNode = new IIOMetadataNode("TIFFAsciis");
IIOMetadataNode childAsciiNode = new IIOMetadataNode("TIFFAscii");
childAsciiNode.setAttribute(FileConstants.TIFF_FIELD_VALUE_ATTRIBUTE, "N");
asciiNode.appendChild(childAsciiNode);
childNode.appendChild(asciiNode);
gpsRootNode.appendChild(childNode);
ifd.appendChild(gpsRootNode);
//Update metadata with new tree
metadata.setFromTree(FileConstants.TIFF_METADATA_FORMAT, root);
ImageOutputStream outstr = ImageIO.createImageOutputStream(writeTarget);
writer.setOutput(outstr);
//Write the image
IIOImage img = new IIOImage(renderedImage, Collections.<BufferedImage> emptyList(), metadata);
writer.write(img);
outstr.close();

	public static String TIFF_METADATA_FORMAT = "javax_imageio_tiff_image_1.0";
	public static String TIFF_FIELD_TAG =       "TIFFField";
	public static String TIFF_ASCIIS_TAG =      "TIFFAsciis";
	public static String TIFF_ASCII_TAG =       "TIFFAscii";
	public static String TIFF_RATIONALS_TAG =   "TIFFRationals";
	public static String TIFF_RATIONAL_TAG =    "TIFFRational";
	public static String TIFF_FIELD_VALUE_ATTRIBUTE = "value";
	     */
	    
	    
	    
//	    imageMetadata.appendChild(dimension);
	    
	    
////		IIOMetadataNode root_dimension = new IIOMetadataNode(TIFF_METADATA_FORMAT); // IIOMetadataFormatImpl.standardMetadataFormatName);
//		root_dimension.appendChild(dimension);
////		root_dimension.appendChild(root_new);
////	    System.out.println("\n=== root_new ===:"); // should have 2 tagSets, but has only baseline
	    /*
	    <javax_imageio_tiff_image_1.0>
        <TIFFIFD tagSets='javax.imageio.plugins.tiff.BaselineTIFFTagSet,javax.imageio.plugins.tiff.GeoTIFFTagSet'>
	    */
	    System.out.println("\n=== root_new ===:");
	    DumpImageMetadata.displayMetadataNode(root_new, 1);
	    System.out.println("\n=== imageMetadata - before merge ===:");
	    DumpImageMetadata.displayMetadataNode(imageMetadata.getAsTree(TIFF_METADATA_FORMAT), 1);
		
		// lost GPS data after merge
	    if (debugLevel > 0) {
	    	System.out.println("\n=== ifd ===:");DumpImageMetadata.displayMetadataNode(ifd, 1);
	    	System.out.println("\n=== root_new ===:"); DumpImageMetadata.displayMetadataNode(root_new, 1);
	    	System.out.println("\n=== imageMetadata - before merge ===:"); DumpImageMetadata.displayMetadataNode(imageMetadata.getAsTree(TIFF_METADATA_FORMAT), 1);
	    }
		try {
			imageMetadata.mergeTree(TIFF_METADATA_FORMAT, root_new); // dimension); // Root must have "TIFFIFD" child
//			imageMetadata.setFromTree(TIFF_METADATA_FORMAT, root_dimension); // dimension);
		} catch (IIOInvalidTreeException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return;
		}
	    
	    System.out.println("\n=== imageMetadata - after merge ===:");
	    DumpImageMetadata.displayMetadataNode(imageMetadata.getAsTree(TIFF_METADATA_FORMAT), 1);
		
		
		
		
	    System.out.println();
		if (debugLevel > 0) {System.out.println("\n=== imageMetadata - after merge ===:");DumpImageMetadata.displayMetadataNode(imageMetadata.getAsTree(TIFF_METADATA_FORMAT), 1);}
	    FileImageOutputStream outputStream;
	    try {
			outputStream = new FileImageOutputStream(outputFile);
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			return;
		}		
	    tiffWriter.setOutput(outputStream);
//	    IIOImage image_with_metadata = new IIOImage(bufferedImage, null, primaryIFD);
//	    IIOImage image_with_metadata = new IIOImage(bufferedImage, null, null);
	    IIOImage image_with_metadata = new IIOImage(bufferedImageAlpha, null, imageMetadata);
	    System.out.println();
        try {
@@ -315,12 +162,11 @@ outstr.close();
					image_with_metadata,
			        tiffWriteParam);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    System.out.println();
        
	}
	
	private static IIOMetadataNode createRationalDegrees(double d, int digits_after) { // 8
		int denom = 1;
		for (int i = 0; i < digits_after; i++) denom *= 10;
@@ -380,7 +226,9 @@ outstr.close();
	    return node_date;
	}
	
	private static IIOMetadataNode createGpsMetadata(double [] lla, LocalDateTime dt) {
	private static IIOMetadataNode createGpsMetadata(
			double [] lla,
			LocalDateTime dt) {
		int ang_sec_after = 5;
		int meters_after =  3;
		int seconds_after = 3;
@@ -390,13 +238,15 @@ outstr.close();
	    gpsRootNode.setAttribute("parentTagNumber", "34853");
	    gpsRootNode.setAttribute("parentTagName",   "GPSInfoIFDPointer");
	    gpsRootNode.setAttribute("tagSets", "javax.imageio.plugins.tiff.ExifGPSTagSet");
        boolean lat_south = lla[0] < 0;
        double lat_abs = Math.abs(lla[0]);
        boolean long_west = lla[1] < 0;
        double long_abs = Math.abs(lla[1]);
        boolean alt_down = lla[2] < 0;
        double alt_abs = Math.abs(lla[2]);
        
        boolean lat_south, long_west, alt_down;
        double lat_abs, long_abs, alt_abs;
        if (lla != null) {
        	lat_south = lla[0] < 0;
        	lat_abs = Math.abs(lla[0]);
        	long_west = lla[1] < 0;
        	long_abs = Math.abs(lla[1]);
        	alt_down = lla[2] < 0;
        	alt_abs = Math.abs(lla[2]);
        	// Latitude
        	IIOMetadataNode node_lat_ref = new IIOMetadataNode(TIFF_FIELD_TAG);
        	node_lat_ref.setAttribute("number", "1");
@@ -412,10 +262,6 @@ outstr.close();
        	node_lat.setAttribute("name", "GPSLatitude");
        	node_lat.appendChild(createRationalDegrees(lat_abs, ang_sec_after));
        	gpsRootNode.appendChild(node_lat);

	    System.out.println("\n=== gpsRootNode after latitude ===:");
	    DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);

        	// Longitude
        	IIOMetadataNode node_long_ref = new IIOMetadataNode(TIFF_FIELD_TAG);
        	node_long_ref.setAttribute("number", "3");
@@ -431,10 +277,6 @@ outstr.close();
        	node_long.setAttribute("name", "GPSLongitude");
        	node_long.appendChild(createRationalDegrees(long_abs, ang_sec_after));
        	gpsRootNode.appendChild(node_long);

	    System.out.println("\n=== gpsRootNode after longitude ===:");
	    DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
	    
        	// Altitude
        	IIOMetadataNode node_alt_ref = new IIOMetadataNode(TIFF_FIELD_TAG);
        	node_alt_ref.setAttribute("number", "5");
@@ -451,10 +293,7 @@ outstr.close();
        	node_alt.setAttribute("name", "GPSAltitude");
        	node_alt.appendChild(createRationalMeters(alt_abs, meters_after));
        	gpsRootNode.appendChild(node_alt);
	    
	    System.out.println("\n=== gpsRootNode after altitude ===:");
	    DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
	    
        }
	    if (dt != null) {
		    // Time
		    IIOMetadataNode node_time = new IIOMetadataNode(TIFF_FIELD_TAG);
@@ -462,8 +301,6 @@ outstr.close();
		    node_time.setAttribute("name", "GPSTimeStamp");
		    node_time.appendChild(createTimeStamp(dt,seconds_after));
		    gpsRootNode.appendChild(node_time);
		    System.out.println("\n=== gpsRootNode after time ===:");
		    DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
		    // Date
		    IIOMetadataNode node_date = new IIOMetadataNode(TIFF_FIELD_TAG);
		    node_date.setAttribute("number", "29");
@@ -471,31 +308,16 @@ outstr.close();
		    node_date.appendChild(createDateStamp(dt));
		    gpsRootNode.appendChild(node_date);
	    }
	    System.out.println("\n=== gpsRootNode after date ===:");
	    DumpImageMetadata.displayMetadataNode(gpsRootNode, 1);
	    return gpsRootNode;
	}
	
	private static IIOMetadataNode createResolutionMetadataStd(double resolutionPixelInMeters) {
//		String pixelSize = Double.toString(25.4 / resolutionDPI);
		String pixelSize = Double.toString(1000*resolutionPixelInMeters); // millimeters
		IIOMetadataNode horizontal = new IIOMetadataNode("HorizontalPixelSize");
		horizontal.setAttribute("value", pixelSize);
		IIOMetadataNode vertical = new IIOMetadataNode("VerticalPixelSize");
		vertical.setAttribute("value", pixelSize);
		IIOMetadataNode dimension = new IIOMetadataNode("Dimension");
		dimension.appendChild(horizontal);
		dimension.appendChild(vertical);
		return dimension;
//		IIOMetadataNode root = new IIOMetadataNode(IIOMetadataFormatImpl.standardMetadataFormatName);
//		root.appendChild(dimension);
//		return root;
	}
	
	private static void addResolutionMetadata(
			IIOMetadataNode ifd,
			double          resolutionPixelInMeters,
			double          resolutionPixelInMeters, // NaN for undefined
			int             digits_after) {
		if (Double.isNaN(resolutionPixelInMeters)) {
			return;
		}
		int denom = 1;
		for (int i = 0; i < digits_after; i++) denom *= 10;
		int fppcm = (int) Math.round(denom * 0.01/resolutionPixelInMeters); // pixels per cm 
@@ -532,41 +354,6 @@ outstr.close();
    	ifd.appendChild(node_y_resolution);
	}
	
/*
 * 
    	IIOMetadataNode node_rationals = new IIOMetadataNode(TIFF_RATIONALS_TAG);
	    IIOMetadataNode node_hrs =       new IIOMetadataNode(TIFF_RATIONAL_TAG);
	    node_hrs.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, dt.getHour()+"/1");
	    IIOMetadataNode node_mins =      new IIOMetadataNode(TIFF_RATIONAL_TAG);
	    node_mins.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, dt.getMinute()+"/1");
	    IIOMetadataNode node_secs =      new IIOMetadataNode(TIFF_RATIONAL_TAG);
	    node_secs.setAttribute(TIFF_FIELD_VALUE_ATTRIBUTE, fsec+"/"+denom);
	    node_rationals.appendChild(node_hrs);
	    node_rationals.appendChild(node_mins);
	    node_rationals.appendChild(node_secs);
 * 
 * The number of pixels per ResolutionUnit in the ImageWidth direction.
            <TIFFField number='282' name='XResolution'>
                <TIFFRationals>
                    <TIFFRational value='1/1'/>
                </TIFFRationals>
            </TIFFField>
            <TIFFField number='283' name='YResolution'>
                <TIFFRationals>
                    <TIFFRational value='1/1'/>
                </TIFFRationals>
            </TIFFField>
            <TIFFField number='296' name='ResolutionUnit'>
                <TIFFShorts>
                    <TIFFShort value='1' description='None'/>
                </TIFFShorts>
            </TIFFField>

	public static String TIFF_SHORTS_TAG =                  "TIFFShorts";
	public static String TIFF_SHORT_TAG =                   "TIFFShort";

 */
	
	/*
	 * 
	FileImageOutputStream outputStream = new FileImageOutputStream(outputFile);
+22 −2

File changed.

Preview size limit exceeded, changes collapsed.

+5 −1
Original line number Diff line number Diff line
@@ -5351,6 +5351,11 @@ public class OpticalFlow {
				quadCLTs[ref_index].saveInterProperties( // save properties for interscene processing (extrinsics, ers, ...)
						null, // String path,             // full name with extension or w/o path to use x3d directory
						debugLevel+1);
			} else {
				if (debugLevel> -3) {
					System.out.println("Failed to perform attitude correction with QuaternionLma.");
				}
				
			}
		}
		
@@ -5946,7 +5951,6 @@ public class OpticalFlow {
		int [] whs = new int[3];
		double [] x0y0 = new double[2];		
		if (export3d) { //combo_dsn_final had strength 1.0e-4 where it should not? Reset it?
			
			boolean ok_3d = TexturedModel.output3d( // quadCLTs have same image name, and everything else
					clt_parameters,      // CLTParameters                            clt_parameters,
					colorProcParameters, // ColorProcParameters                      colorProcParameters,
+12 −2

File changed.

Preview size limit exceeded, changes collapsed.

Loading