Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
imagej-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Elphel
imagej-elphel
Commits
6894dccd
Commit
6894dccd
authored
Dec 04, 2023
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Trying to get GPS data
parent
db9a0992
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1192 additions
and
94 deletions
+1192
-94
pom.xml
pom.xml
+29
-6
EyesisCorrections.java
.../java/com/elphel/imagej/correction/EyesisCorrections.java
+2
-2
Eyesis_Correction.java
.../java/com/elphel/imagej/correction/Eyesis_Correction.java
+117
-4
Did_ins.java
src/main/java/com/elphel/imagej/ims/Did_ins.java
+17
-0
ChangeImageResolution.java
...java/com/elphel/imagej/readers/ChangeImageResolution.java
+224
-0
DumpImageMetadata.java
...ain/java/com/elphel/imagej/readers/DumpImageMetadata.java
+239
-0
ElphelTiffReader.java
...main/java/com/elphel/imagej/readers/ElphelTiffReader.java
+0
-3
ElphelTiffWriter.java
...main/java/com/elphel/imagej/readers/ElphelTiffWriter.java
+435
-0
EyesisTiff.java
src/main/java/com/elphel/imagej/readers/EyesisTiff.java
+44
-5
QuadCLTCPU.java
...main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
+85
-74
No files found.
pom.xml
View file @
6894dccd
...
...
@@ -217,21 +217,20 @@
<target>
1.8
</target>
</configuration>
</plugin>
<plugin>
<groupId>
org.codehaus.mojo
</groupId>
<artifactId>
exec-maven-plugin
</artifactId>
<version>
1.3.2
</version>
<!--$NO-MVN-MAN-VER$-->
<version>
1.3.2
</version>
<!--$NO-MVN-MAN-VER$-->
<executions>
<execution>
<phase>
package
</phase>
<phase>
package
</phase>
<goals>
<goal>
java
</goal>
</goals>
</execution>
</executions>
<configuration>
<!--
<mainClass>Aberration_Calibration</mainClass> -->
<!-- <mainClass>Aberration_Calibration</mainClass> -->
<mainClass>
Eyesis_Correction
</mainClass>
</configuration>
</plugin>
...
...
@@ -253,11 +252,35 @@
<format>
Build {0,date,yyyy-MM-dd} {0,time,HH:MM:SS} on host {1}
</format>
<items>
<item>
timestamp
</item>
<!-- <item>foxel-MRHM7AP</item> -->
</items>
</configuration>
</plugin>
</plugin>
<!-- Trying sources/javadocs -->
<plugin>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-dependency-plugin
</artifactId>
<version>
3.1.2
</version>
<executions>
<execution>
<goals>
<goal>
sources
</goal>
<goal>
resolve
</goal>
</goals>
<configuration>
<classifier>
javadoc
</classifier>
</configuration>
</execution>
</executions>
</plugin>
<!-- End of Trying sources/javadocs -->
</plugins>
</pluginManagement>
</build>
...
...
src/main/java/com/elphel/imagej/correction/EyesisCorrections.java
View file @
6894dccd
...
...
@@ -2741,7 +2741,7 @@ public class EyesisCorrections {
}
else
{
if
(
debugLevel
>
0
)
System
.
out
.
println
(
"Saving RGBA result to "
+
path
+
".tiff"
);
try
{
(
new
EyesisTiff
())
.
saveTiffARGB32
(
EyesisTiff
.
saveTiffARGB32
(
imp
,
path
+
".tiff"
,
//path, // +".tiff",
false
,
// correctionsParameters.imageJTags,
...
...
@@ -2777,7 +2777,7 @@ public class EyesisCorrections {
if
((
imp
.
getStackSize
()
==
4
)
&&
imp
.
getStack
().
getSliceLabel
(
4
).
equals
(
"alpha"
)){
try
{
(
new
EyesisTiff
())
.
saveTiff
(
EyesisTiff
.
saveTiff
(
imp
,
path
+
".tiff"
,
mode
,
//
...
...
src/main/java/com/elphel/imagej/correction/Eyesis_Correction.java
View file @
6894dccd
...
...
@@ -43,6 +43,7 @@ import java.awt.event.ActionListener;
import
java.awt.event.MouseAdapter
;
import
java.awt.event.MouseEvent
;
import
java.awt.event.WindowEvent
;
import
java.awt.image.BufferedImage
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
...
...
@@ -70,9 +71,22 @@ import java.util.Properties;
import
java.util.Set
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
javax.imageio.ImageIO
;
import
javax.imageio.ImageTypeSpecifier
;
import
javax.imageio.ImageWriteParam
;
import
javax.imageio.ImageWriter
;
import
javax.imageio.metadata.IIOInvalidTreeException
;
import
javax.imageio.metadata.IIOMetadata
;
import
javax.imageio.metadata.IIOMetadataFormatImpl
;
import
javax.imageio.metadata.IIOMetadataNode
;
import
javax.imageio.plugins.tiff.ExifGPSTagSet
;
import
javax.imageio.plugins.tiff.TIFFDirectory
;
import
javax.imageio.plugins.tiff.TIFFTagSet
;
import
javax.swing.JFileChooser
;
import
javax.swing.filechooser.FileFilter
;
import
org.w3c.dom.Node
;
import
com.elphel.imagej.calibration.CalibrationFileManagement
;
import
com.elphel.imagej.calibration.CalibrationIllustration
;
import
com.elphel.imagej.calibration.CalibrationIllustrationParameters
;
...
...
@@ -95,6 +109,8 @@ import com.elphel.imagej.ims.EventLogger;
import
com.elphel.imagej.ims.Imx5
;
import
com.elphel.imagej.jp4.JP46_Reader_camera
;
import
com.elphel.imagej.lwir.LwirReader
;
import
com.elphel.imagej.readers.ChangeImageResolution
;
import
com.elphel.imagej.readers.DumpImageMetadata
;
import
com.elphel.imagej.readers.EyesisTiff
;
import
com.elphel.imagej.tensorflow.TensorflowInferModel
;
import
com.elphel.imagej.tileprocessor.Clt1d
;
...
...
@@ -578,6 +594,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
if
(
ADVANCED_MODE
)
{
addButton
(
"Tiff Writer"
,
panel7
);
addButton
(
"Tiff Properties"
,
panel7
);
addButton
(
"Add TIFF resolution"
,
panel7
);
}
plugInFrame
.
add
(
panel7
);
...
...
@@ -1662,7 +1679,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
/* ======================================================================== */
}
else
if
(
label
.
equals
(
"Tiff Writer"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
EyesisTiff
eyesisTiff
=
new
EyesisTiff
();
//
EyesisTiff eyesisTiff = new EyesisTiff();
ImagePlus
imp_sel
=
WindowManager
.
getCurrentImage
();
if
(
imp_sel
==
null
)
{
IJ
.
showMessage
(
"Error"
,
"No images selected"
);
...
...
@@ -1676,7 +1693,7 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
}
try
{
try
{
e
yesisTiff
.
saveTiff
(
imp_sel
,
path
,
CORRECTION_PARAMETERS
.
equirectangularFormat
,
E
yesisTiff
.
saveTiff
(
imp_sel
,
path
,
CORRECTION_PARAMETERS
.
equirectangularFormat
,
(
CORRECTION_PARAMETERS
.
equirectangularFormat
==
3
)
?
CORRECTION_PARAMETERS
.
outputRangeFP
:
CORRECTION_PARAMETERS
.
outputRangeInt
,
CORRECTION_PARAMETERS
.
imageJTags
,
DEBUG_LEVEL
);
...
...
@@ -1696,13 +1713,109 @@ public class Eyesis_Correction implements PlugIn, ActionListener {
/* ======================================================================== */
}
else
if
(
label
.
equals
(
"Tiff Properties"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
EyesisTiff
eyesisTiff
=
new
EyesisTiff
();
ImagePlus
imp_sel
=
WindowManager
.
getCurrentImage
();
if
(
imp_sel
==
null
)
{
IJ
.
showMessage
(
"Error"
,
"No images selected"
);
return
;
}
eyesisTiff
.
propertiesTiff
(
imp_sel
);
String
orig_path
=
imp_sel
.
getOriginalFileInfo
().
getFilePath
();
try
{
DumpImageMetadata
.
processFile
(
new
File
(
orig_path
));
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
// EyesisTiff.propertiesTiff(imp_sel);
return
;
/* ======================================================================== */
}
else
if
(
label
.
equals
(
"Add TIFF resolution"
))
{
DEBUG_LEVEL
=
MASTER_DEBUG_LEVEL
;
ImagePlus
imp_sel
=
WindowManager
.
getCurrentImage
();
if
(
imp_sel
==
null
)
{
IJ
.
showMessage
(
"Error"
,
"No images selected"
);
return
;
}
String
orig_path
=
imp_sel
.
getOriginalFileInfo
().
getFilePath
();
// Testing change image resolution
File
inputFile
=
new
File
(
orig_path
);
IIOMetadata
inMetadata
=
null
;
try
{
inMetadata
=
DumpImageMetadata
.
getFileMetadata
(
inputFile
);
}
catch
(
IOException
e1
)
{
// TODO Auto-generated catch block
e1
.
printStackTrace
();
return
;
}
double
resolutionDPI
=
600
;
File
outputFile
=
new
File
(
orig_path
+
"_"
+((
int
)
resolutionDPI
)+
"-01.tiff"
);
BufferedImage
image
=
null
;
try
{
image
=
ChangeImageResolution
.
readImage
(
inputFile
);
// wrong imageType 0 (should be 2)
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
return
;
}
IIOMetadataNode
newMetadata
=
ChangeImageResolution
.
createResolutionMetadata
(
resolutionDPI
);
// IIOMetadataNode addMetadata = ChangeImageResolution.createResolutionMetadata0(resolutionDPI);
// inMetaData.appendChild()
try
{
inMetadata
.
mergeTree
(
IIOMetadataFormatImpl
.
standardMetadataFormatName
,
newMetadata
);
}
catch
(
IIOInvalidTreeException
e1
)
{
// TODO Auto-generated catch block
e1
.
printStackTrace
();
return
;
}
Node
metadata_as_tree
=
inMetadata
.
getAsTree
(
"javax_imageio_tiff_image_1.0"
);
BufferedImage
bufferedImageAlpha
=
new
BufferedImage
(
image
.
getWidth
(),
image
.
getHeight
(),
BufferedImage
.
TYPE_INT_ARGB
);
ImageWriter
tiffWriter
=
ImageIO
.
getImageWritersByFormatName
(
"tiff"
).
next
();
ImageWriteParam
tiffWriteParam
=
tiffWriter
.
getDefaultWriteParam
();
tiffWriteParam
.
setCompressionMode
(
ImageWriteParam
.
MODE_DISABLED
);
ImageTypeSpecifier
imageType
=
ImageTypeSpecifier
.
createFromRenderedImage
(
bufferedImageAlpha
);
IIOMetadata
imageMetadata
=
tiffWriter
.
getDefaultImageMetadata
(
imageType
,
tiffWriteParam
);
TIFFDirectory
directory
=
null
;
try
{
directory
=
TIFFDirectory
.
createFromMetadata
(
imageMetadata
);
}
catch
(
IIOInvalidTreeException
e2
)
{
// TODO Auto-generated catch block
e2
.
printStackTrace
();
}
/// TIFFTagSet tag_set = ExifGPSTagSet.getInstance();
/// directory.addTagSet(tag_set); // ExifGPSTagSet.getInstance());
//// imageMetadata = directory.getAsMetadata();
System
.
out
.
println
(
"\n=== metadata_as_tree ===:"
);
DumpImageMetadata
.
displayMetadataNode
(
metadata_as_tree
,
1
);
System
.
out
.
println
(
"\n=== imageMetadata as javax_imageio_tiff_image_1.0 ===:"
);
DumpImageMetadata
.
displayMetadataNode
(
imageMetadata
.
getAsTree
(
"javax_imageio_tiff_image_1.0"
),
1
);
try
{
// imageMetadata.mergeTree(IIOMetadataFormatImpl.standardMetadataFormatName, metadata_as_tree);
imageMetadata
.
mergeTree
(
"javax_imageio_tiff_image_1.0"
,
metadata_as_tree
);
}
catch
(
IIOInvalidTreeException
e1
)
{
// TODO Auto-generated catch block
e1
.
printStackTrace
();
return
;
}
System
.
out
.
println
(
"\n=== imageMetadata merged as javax_imageio_tiff_image_1.0 ===:"
);
DumpImageMetadata
.
displayMetadataNode
(
imageMetadata
.
getAsTree
(
"javax_imageio_tiff_image_1.0"
),
1
);
// works with inMetadata. Will it with imageMetadata?
try
{
ChangeImageResolution
.
writeImage
(
outputFile
,
image
,
imageMetadata
);
// inMetadata); // newMetadata);
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
return
;
/* ======================================================================== */
}
else
if
(
label
.
equals
(
"Configure PP"
))
{
...
...
src/main/java/com/elphel/imagej/ims/Did_ins.java
View file @
6894dccd
package
com
.
elphel
.
imagej
.
ims
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.util.Properties
;
import
com.elphel.imagej.tileprocessor.IntersceneMatchParameters
;
public
abstract
class
Did_ins
<
T
extends
Did_ins
<
T
>>{
final
static
LocalDateTime
DT_01_06_1980
=
LocalDateTime
.
of
(
1980
,
1
,
6
,
0
,
0
);
final
static
int
WEEK_SECONDS
=
7
*
24
*
3600
;
/** GPS number of weeks since January 6th, 1980 */
public
int
week
;
// uint32_t
...
...
@@ -49,6 +52,20 @@ public abstract class Did_ins <T extends Did_ins <T>>{
return
new
int
[]
{
week
,
(
int
)
Math
.
round
(
timeOfWeek
*
1000.0
)};
}
public
static
LocalDateTime
getLocalDateTime
(
int
week
,
double
tow
)
{
/** GPS number of weeks since January 6th, 1980 */
/** GPS time of week (since Sunday morning) in seconds */
int
seconds
=
(
int
)
Math
.
floor
(
tow
);
int
nanos
=
(
int
)
Math
.
floor
((
tow
-
seconds
)*
1
E9
);
return
DT_01_06_1980
.
plusWeeks
(
week
).
plusSeconds
(
seconds
).
plusNanos
(
nanos
);
}
public
LocalDateTime
getLocalDateTime
()
{
return
getLocalDateTime
(
week
,
timeOfWeek
);
}
public
boolean
isDidSane
()
{
if
((
week
<
MIN_WEEK
)
||
(
week
>
MAX_WEEK
))
{
System
.
out
.
println
(
"isDidSane(): bad week = "
+
week
+
...
...
src/main/java/com/elphel/imagej/readers/ChangeImageResolution.java
0 → 100644
View file @
6894dccd
package
com
.
elphel
.
imagej
.
readers
;
//https://www.silverbaytech.com/2014/06/04/iiometadata-tutorial-part-3-writing-metadata/
/*
* Copyright (c) 2014 Kevin Hunter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//package com.silverbaytech.blog.imageIoMetadata;
import
java.awt.image.BufferedImage
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.Iterator
;
import
javax.imageio.IIOImage
;
import
javax.imageio.ImageIO
;
import
javax.imageio.ImageReader
;
import
javax.imageio.ImageTypeSpecifier
;
import
javax.imageio.ImageWriteParam
;
import
javax.imageio.ImageWriter
;
import
javax.imageio.metadata.IIOMetadata
;
import
javax.imageio.metadata.IIOMetadataFormatImpl
;
import
javax.imageio.metadata.IIOMetadataNode
;
import
javax.imageio.stream.ImageInputStream
;
import
javax.imageio.stream.ImageOutputStream
;
public
class
ChangeImageResolution
{
private
static
String
getFileExtension
(
File
file
)
{
String
fileName
=
file
.
getName
();
int
lastDot
=
fileName
.
lastIndexOf
(
'.'
);
return
fileName
.
substring
(
lastDot
+
1
);
}
public
static
BufferedImage
readImage
(
File
file
)
throws
IOException
{
ImageInputStream
stream
=
null
;
BufferedImage
image
=
null
;
try
{
stream
=
ImageIO
.
createImageInputStream
(
file
);
Iterator
<
ImageReader
>
readers
=
ImageIO
.
getImageReaders
(
stream
);
if
(
readers
.
hasNext
())
{
ImageReader
reader
=
readers
.
next
();
reader
.
setInput
(
stream
);
image
=
reader
.
read
(
0
);
}
}
finally
{
if
(
stream
!=
null
)
{
stream
.
close
();
}
}
return
image
;
}
//https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/javax/imageio/metadata/doc-files/standard_metadata.html
public
static
IIOMetadataNode
createResolutionMetadata
(
double
resolutionDPI
)
{
String
pixelSize
=
Double
.
toString
(
25.4
/
resolutionDPI
);
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
);
IIOMetadataNode
root
=
new
IIOMetadataNode
(
IIOMetadataFormatImpl
.
standardMetadataFormatName
);
root
.
appendChild
(
dimension
);
return
root
;
}
public
static
IIOMetadataNode
createResolutionMetadata0
(
double
resolutionDPI
)
{
String
pixelSize
=
Double
.
toString
(
25.4
/
resolutionDPI
);
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;
}
public
static
void
writeImage
(
File
outputFile
,
BufferedImage
image
,
IIOMetadataNode
newMetadata
)
throws
IOException
{
String
extension
=
getFileExtension
(
outputFile
);
ImageTypeSpecifier
imageType
=
ImageTypeSpecifier
.
createFromBufferedImageType
(
image
.
getType
());
ImageOutputStream
stream
=
null
;
try
{
Iterator
<
ImageWriter
>
writers
=
ImageIO
.
getImageWritersBySuffix
(
extension
);
while
(
writers
.
hasNext
())
{
ImageWriter
writer
=
writers
.
next
();
ImageWriteParam
writeParam
=
writer
.
getDefaultWriteParam
();
IIOMetadata
imageMetadata
=
writer
.
getDefaultImageMetadata
(
imageType
,
writeParam
);
if
(!
imageMetadata
.
isStandardMetadataFormatSupported
())
{
continue
;
}
if
(
imageMetadata
.
isReadOnly
())
{
continue
;
}
imageMetadata
.
mergeTree
(
IIOMetadataFormatImpl
.
standardMetadataFormatName
,
newMetadata
);
IIOImage
imageWithMetadata
=
new
IIOImage
(
image
,
null
,
imageMetadata
);
stream
=
ImageIO
.
createImageOutputStream
(
outputFile
);
writer
.
setOutput
(
stream
);
writer
.
write
(
null
,
imageWithMetadata
,
writeParam
);
}
}
finally
{
if
(
stream
!=
null
)
{
stream
.
close
();
}
}
}
public
static
void
writeImage
(
File
outputFile
,
BufferedImage
image
,
IIOMetadata
newMetadata
)
throws
IOException
{
String
extension
=
getFileExtension
(
outputFile
);
ImageTypeSpecifier
imageType
=
ImageTypeSpecifier
.
createFromBufferedImageType
(
image
.
getType
());
ImageOutputStream
stream
=
null
;
try
{
Iterator
<
ImageWriter
>
writers
=
ImageIO
.
getImageWritersBySuffix
(
extension
);
while
(
writers
.
hasNext
())
{
ImageWriter
writer
=
writers
.
next
();
ImageWriteParam
writeParam
=
writer
.
getDefaultWriteParam
();
/*
IIOMetadata imageMetadata = writer.getDefaultImageMetadata(imageType, writeParam);
if (!imageMetadata.isStandardMetadataFormatSupported())
{
continue;
}
if (imageMetadata.isReadOnly())
{
continue;
}
imageMetadata.mergeTree(IIOMetadataFormatImpl.standardMetadataFormatName, newMetadata);
*/
IIOImage
imageWithMetadata
=
new
IIOImage
(
image
,
null
,
newMetadata
);
stream
=
ImageIO
.
createImageOutputStream
(
outputFile
);
writer
.
setOutput
(
stream
);
writer
.
write
(
null
,
imageWithMetadata
,
writeParam
);
}
}
finally
{
if
(
stream
!=
null
)
{
stream
.
close
();
}
}
}
public
static
void
main
(
String
[]
args
)
{
if
(
args
.
length
!=
3
)
{
System
.
out
.
println
(
"Usage: ChangeImageResolution inputFile newResolutionDPI outputFile"
);
return
;
}
try
{
File
inputFile
=
new
File
(
args
[
0
]);
double
resolutionDPI
=
Double
.
parseDouble
(
args
[
1
]);
File
outputFile
=
new
File
(
args
[
2
]);
BufferedImage
image
=
readImage
(
inputFile
);
IIOMetadataNode
newMetadata
=
createResolutionMetadata
(
resolutionDPI
);
writeImage
(
outputFile
,
image
,
newMetadata
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
}
src/main/java/com/elphel/imagej/readers/DumpImageMetadata.java
0 → 100644
View file @
6894dccd
/*
https://www.silverbaytech.com/2014/05/29/iiometadata-tutorial-part-2-retrieving-image-metadata/
*/
package
com
.
elphel
.
imagej
.
readers
;
/*
* Copyright (c) 2014 Kevin Hunter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//package com.silverbaytech.blog.imageIoMetadata;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.Iterator
;
import
javax.imageio.ImageIO
;
import
javax.imageio.ImageReader
;
import
javax.imageio.metadata.IIOMetadata
;
import
javax.imageio.stream.ImageInputStream
;
import
org.w3c.dom.NamedNodeMap
;
import
org.w3c.dom.Node
;
/**
* Dump the ImageIO metadata associated with one or more images.
*
* @author Kevin Hunter
*
*/
public
class
DumpImageMetadata
{
private
static
String
getFileExtension
(
File
file
)
{
String
fileName
=
file
.
getName
();
int
lastDot
=
fileName
.
lastIndexOf
(
'.'
);
return
fileName
.
substring
(
lastDot
+
1
);
}
private
static
void
indent
(
int
level
)
{
for
(
int
i
=
0
;
i
<
level
;
i
++)
{
System
.
out
.
print
(
" "
);
}
}
private
static
void
displayAttributes
(
NamedNodeMap
attributes
)
{
if
(
attributes
!=
null
)
{
int
count
=
attributes
.
getLength
();
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
Node
attribute
=
attributes
.
item
(
i
);
System
.
out
.
print
(
" "
);
System
.
out
.
print
(
attribute
.
getNodeName
());
System
.
out
.
print
(
"='"
);
System
.
out
.
print
(
attribute
.
getNodeValue
());
System
.
out
.
print
(
"'"
);
}
}
}
public
static
void
displayMetadataNode
(
Node
node
,
int
level
)
{
indent
(
level
);
System
.
out
.
print
(
"<"
);
System
.
out
.
print
(
node
.
getNodeName
());
NamedNodeMap
attributes
=
node
.
getAttributes
();
displayAttributes
(
attributes
);
Node
child
=
node
.
getFirstChild
();
if
(
child
==
null
)
{
String
value
=
node
.
getNodeValue
();
if
(
value
==
null
||
value
.
length
()
==
0
)
{
System
.
out
.
println
(
"/>"
);
}
else
{
System
.
out
.
print
(
">"
);
System
.
out
.
print
(
value
);
System
.
out
.
print
(
"<"
);
System
.
out
.
print
(
node
.
getNodeName
());
System
.
out
.
println
(
">"
);
}
return
;
}
System
.
out
.
println
(
">"
);
while
(
child
!=
null
)
{
displayMetadataNode
(
child
,
level
+
1
);
child
=
child
.
getNextSibling
();
}
indent
(
level
);
System
.
out
.
print
(
"</"
);
System
.
out
.
print
(
node
.
getNodeName
());
System
.
out
.
println
(
">"
);
}
private
static
void
dumpMetadata
(
IIOMetadata
metadata
)
{
String
[]
names
=
metadata
.
getMetadataFormatNames
();
int
length
=
names
.
length
;
for
(
int
i
=
0
;
i
<
length
;
i
++)
{
indent
(
2
);
System
.
out
.
println
(
"Format name: "
+
names
[
i
]);
displayMetadataNode
(
metadata
.
getAsTree
(
names
[
i
]),
3
);
}
}
private
static
void
processFileWithReader
(
File
file
,
ImageReader
reader
)
throws
IOException
{
ImageInputStream
stream
=
null
;
try
{
stream
=
ImageIO
.
createImageInputStream
(
file
);
reader
.
setInput
(
stream
,
true
);
IIOMetadata
metadata
=
reader
.
getImageMetadata
(
0
);
indent
(
1
);
System
.
out
.
println
(
"Image metadata"
);
dumpMetadata
(
metadata
);
IIOMetadata
smetadata
=
reader
.
getStreamMetadata
();
if
(
smetadata
!=
null
)
{
indent
(
1
);
System
.
out
.
println
(
"Stream metadata"
);
dumpMetadata
(
smetadata
);
}
}
finally
{
if
(
stream
!=
null
)
{
stream
.
close
();
}
}
}
public
static
void
processFile
(
File
file
)
throws
IOException
{
System
.
out
.
println
(
"\nProcessing "
+
file
.
getName
()
+
":\n"
);
String
extension
=
getFileExtension
(
file
);
Iterator
<
ImageReader
>
readers
=
ImageIO
.
getImageReadersByFormatName
(
extension
);
while
(
readers
.
hasNext
())
{
ImageReader
reader
=
readers
.
next
();
System
.
out
.
println
(
"Reader: "
+
reader
.
getClass
().
getName
());
processFileWithReader
(
file
,
reader
);
}
}
public
static
IIOMetadata
getFileMetadata
(
File
file
)
throws
IOException
{
String
extension
=
getFileExtension
(
file
);
Iterator
<
ImageReader
>
readers
=
ImageIO
.
getImageReadersByFormatName
(
extension
);
IIOMetadata
metadata
=
null
;
if
(
readers
.
hasNext
())
{
ImageReader
reader
=
readers
.
next
();
System
.
out
.
println
(
"Reader: "
+
reader
.
getClass
().
getName
());
// processFileWithReader(file, reader);
ImageInputStream
stream
=
null
;
try
{
stream
=
ImageIO
.
createImageInputStream
(
file
);
reader
.
setInput
(
stream
,
true
);
metadata
=
reader
.
getImageMetadata
(
0
);
}
finally
{
if
(
stream
!=
null
)
{
stream
.
close
();
}
}
}
return
metadata
;
}
public
static
void
processDirectory
(
File
directory
)
throws
IOException
{
System
.
out
.
println
(
"Processing all files in "
+
directory
.
getAbsolutePath
());
File
[]
contents
=
directory
.
listFiles
();
for
(
File
file
:
contents
)
{
if
(
file
.
isFile
())
{
processFile
(
file
);
}
}
}
public
static
void
main
(
String
[]
args
)
{
try
{
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
File
fileOrDirectory
=
new
File
(
args
[
i
]);
if
(
fileOrDirectory
.
isFile
())
{
processFile
(
fileOrDirectory
);
}
else
{
processDirectory
(
fileOrDirectory
);
}
}
System
.
out
.
println
(
"\nDone"
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
\ No newline at end of file
src/main/java/com/elphel/imagej/readers/ElphelTiffReader.java
View file @
6894dccd
...
...
@@ -59,9 +59,6 @@ import loci.formats.FormatTools;
import
loci.formats.in.MetadataLevel
;
import
loci.formats.in.TiffReader
;
import
loci.formats.meta.MetadataStore
;
import
loci.formats.tiff.IFD
;
import
loci.formats.tiff.IFDList
;
import
loci.formats.tiff.TiffRational
;
import
ome.xml.model.primitives.Timestamp
;
/*
...
...
src/main/java/com/elphel/imagej/readers/ElphelTiffWriter.java
0 → 100644
View file @
6894dccd
/**
**
** ElphelTiffWriter - Write Tiff files w/o loci
**
** Copyright (C) 2023 Elphel, Inc.
**
** -----------------------------------------------------------------------------**
**
** ElphelTiffWriter.java is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 3 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program. If not, see <http://www.gnu.org/licenses/>.
** -----------------------------------------------------------------------------**
**
*/
package
com
.
elphel
.
imagej
.
readers
;
import
java.awt.image.BufferedImage
;
import
java.awt.image.ColorModel
;
import
java.awt.image.DataBufferInt
;
import
java.awt.image.Raster
;
import
java.awt.image.SampleModel
;
import
java.io.File
;
import
java.io.IOException
;
import
java.time.LocalDateTime
;
import
javax.imageio.IIOImage
;
import
javax.imageio.ImageIO
;
import
javax.imageio.ImageTypeSpecifier
;
import
javax.imageio.ImageWriteParam
;
import
javax.imageio.ImageWriter
;
import
javax.imageio.metadata.IIOInvalidTreeException
;
import
javax.imageio.metadata.IIOMetadata
;
import
javax.imageio.metadata.IIOMetadataFormatImpl
;
import
javax.imageio.metadata.IIOMetadataNode
;
import
javax.imageio.stream.FileImageOutputStream
;
import
javax.imageio.plugins.tiff.TIFFDirectory
;
import
javax.imageio.plugins.tiff.TIFFTagSet
;
import
javax.imageio.plugins.tiff.ExifGPSTagSet
;
import
javax.imageio.plugins.tiff.ExifParentTIFFTagSet
;
import
javax.imageio.plugins.tiff.TIFFField
;
import
org.w3c.dom.Node
;
import
com.elphel.imagej.ims.Did_ins
;
import
ij.ImagePlus
;
public
class
ElphelTiffWriter
{
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"
;
public
static
void
saveTiffARGB32
(
ImagePlus
imp
,
String
path
,
boolean
imageJTags
,
int
debugLevel
)
{
// ImageWriter tiffWriter;
// ImageWriteParam tiffWriteParam;
IIOMetadata
tiffStreamMetadata
;
IIOMetadata
primaryIFD
;
BufferedImage
bufferedImage
=
(
BufferedImage
)
imp
.
getImage
();
// properties=null
BufferedImage
thumbnail
;
File
outputFile
=
new
File
(
path
);
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);
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
BufferedImage
bufferedImageAlpha
=
new
BufferedImage
(
bufferedImage
.
getWidth
(),
bufferedImage
.
getHeight
(),
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
;
/*
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
);
}
catch
(
IIOInvalidTreeException
e2
)
{
// TODO Auto-generated catch block
e2
.
printStackTrace
();
}
TIFFTagSet
tag_set
=
ExifGPSTagSet
.
getInstance
();
TIFFTagSet
eptts
=
ExifParentTIFFTagSet
.
getInstance
();
directory
.
addTagSet
(
tag_set
);
// ExifGPSTagSet.getInstance());
directory
.
addTagSet
(
eptts
);
// ExifParentTIFFTagSet.getInstance());
//ExifGPSTagSet
imageMetadata
=
directory
.
getAsMetadata
();
/* */
Node
root_gps
=
imageMetadata
.
getAsTree
(
TIFF_METADATA_FORMAT
);
//?
System
.
out
.
println
(
"\n=== root_gps ===:"
);
DumpImageMetadata
.
displayMetadataNode
(
root_gps
,
1
);
Node
ifd
=
root_gps
.
getFirstChild
();
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
);
ifd
.
appendChild
(
gpsRootNode
);
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";
*/
IIOMetadataNode
dimension
=
createResolutionMetadata
(
pix_in_meters
);
// imageMetadata.appendChild(dimension);
//// IIOMetadataNode root_dimension = new IIOMetadataNode(TIFF_METADATA_FORMAT); // IIOMetadataFormatImpl.standardMetadataFormatName);
// root_dimension.appendChild(dimension);
//// root_dimension.appendChild(root_gps);
System
.
out
.
println
(
"\n=== root_gps ===:"
);
// 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'>
*/
DumpImageMetadata
.
displayMetadataNode
(
root_gps
,
1
);
System
.
out
.
println
(
"\n=== imageMetadata - before merge ===:"
);
DumpImageMetadata
.
displayMetadataNode
(
imageMetadata
.
getAsTree
(
TIFF_METADATA_FORMAT
),
1
);
// lost GPS data after merge
try
{
imageMetadata
.
mergeTree
(
TIFF_METADATA_FORMAT
,
root_gps
);
// 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
();
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
{
tiffWriter
.
write
(
null
,
// tiffStreamMetadata,
image_with_metadata
,
tiffWriteParam
);
}
catch
(
IOException
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
System
.
out
.
println
();
}
private
static
IIOMetadataNode
createResolutionMetadata
(
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
IIOMetadataNode
createGpsMetadata
(
double
[]
lla
,
LocalDateTime
dt
)
{
IIOMetadataNode
gpsRootNode
=
new
IIOMetadataNode
(
"TIFFIFD"
);
// gpsRootNode.setAttribute(FileConstants.TIFF_FIELD_NUMBER_ATTRIBUTE, "34853");
return
gpsRootNode
;
}
/*
*
FileImageOutputStream outputStream = new FileImageOutputStream(outputFile);
writer.setOutput(outputStream);
IIOImage image = new IIOImage(outputImage, null, null);
writer.write(null, image, imageWriteParam);
writer.dispose();
*
*
*
image BufferedImage (id=191)
accelerationPriority 0.5
colorModel DirectColorModel (id=192)
imageType 1
osis null
properties null
raster IntegerInterleavedRaster (id=196)
surfaceManager null
*/
/*
public static void saveTiffARGB32(
ImagePlus imp,
String path,
boolean imageJTags,
int debugLevel
) throws IOException, FormatException, ServiceException, DependencyException{
int IFDImageFullWidth= 0x8214; // not defined in loci.formats.tiff.IFD
int IFDImageFullLength=0x8215; // not defined in loci.formats.tiff.IFD
// public static final int META_DATA_BYTE_COUNTS = 50838; // private tag registered with Adobe
// public static final int META_DATA = 50839; // private tag registered with Adobe
int IFDImageJByteCounts= 0xc696; // was array {12( if no slices, roi, etc.), bytes in info}
int IFDImageJInfo= 0xc697; // ImageJ info, starting with magic IJIJinfo,
byte [] ImageJInfoMagic={73,74,73,74,105,110,102,111,0,0,0,1};
int pixelsDenominator=1000;
String description=(imp.getProperty("description")!=null)?((String) imp.getProperty("description")):"Elphel Eyesis4pi";
int [] iPixels= (int []) imp.getProcessor().getPixels();
byte [] bytes=new byte[iPixels.length*4];
int pIndex=0;
for (int i=0;i<iPixels.length;i++){
bytes[pIndex++]=(byte) ((iPixels[i]>>16)& 0xff); // R
bytes[pIndex++]=(byte) ((iPixels[i]>> 8)& 0xff); // G
bytes[pIndex++]=(byte) ((iPixels[i]>> 0)& 0xff); // B
bytes[pIndex++]=(byte) ((iPixels[i]>>24)& 0xff); // alpha
}
IFD ifd=new IFD();
ifd.put(IFD.LITTLE_ENDIAN, false);
// ifd.put(new Integer(IFD.LITTLE_ENDIAN), new Boolean(true));
ifd.put(IFD.IMAGE_WIDTH, imp.getWidth());
ifd.put(IFD.IMAGE_LENGTH, imp.getHeight());
ifd.put(IFD.SAMPLES_PER_PIXEL, 4);
ifd.putIFDValue(IFD.SOFTWARE, "Elphel Eyesis");
ifd.putIFDValue(IFD.IMAGE_DESCRIPTION, description);
// copy some other data?
ifd.putIFDValue(IFD.COMPRESSION, 1); //TiffCompression.UNCOMPRESSED);
ifd.putIFDValue(IFD.PHOTOMETRIC_INTERPRETATION,2); // RGB
ifd.putIFDValue(IFD.EXTRA_SAMPLES,2); // extra 2 bytes (over 3) meaning Unassociated alpha data
// ifd.putIFDValue(IFD.EXTRA_SAMPLES,1); // extra 1 byte (over 3) meaning Associated alpha data
ifd.putIFDValue(IFD.SAMPLE_FORMAT,1); //
// int [] bpsArray={8,8,8,8};
// ifd.putIFDValue(IFD.BITS_PER_SAMPLE, bpsArray); // will be done automatically
if (imp.getProperty("XPosition")!=null) {
ifd.putIFDValue(IFD.X_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("XPosition"))) , pixelsDenominator));
}
if (imp.getProperty("YPosition")!=null) {
ifd.putIFDValue(IFD.Y_POSITION,
new TiffRational((int) Math.round(pixelsDenominator*Double.parseDouble((String) imp.getProperty("YPosition"))) , pixelsDenominator));
}
if (imp.getProperty("ImageFullWidth")!=null){
ifd.putIFDValue(IFDImageFullWidth, (long) Integer.parseInt((String) imp.getProperty("ImageFullWidth")));
}
if (imp.getProperty("ImageFullLength")!=null){
ifd.putIFDValue(IFDImageFullLength, (long) Integer.parseInt((String) imp.getProperty("ImageFullLength")));
}
//TODO: Seems to match ImageJ Info, but it is not recognized :-(
if (imageJTags && (imp.getProperty("Info")!=null) && (imp.getProperty("Info") instanceof String)){
int skipFirstBytes=2;
String info=(String) imp.getProperty("Info");
byte [] bInfoBody=info.getBytes("UTF-16");
int [] bInfo = new int [ImageJInfoMagic.length+bInfoBody.length-skipFirstBytes];
int index=0;
for (int i=0;i<ImageJInfoMagic.length;i++) bInfo[index++]=ImageJInfoMagic[i];
for (int i=skipFirstBytes;i<bInfoBody.length; i++) bInfo[index++]=bInfoBody[i]; // first 2 bytes {-2, -1} ???
long [] imageJcounts={12, bInfoBody.length-skipFirstBytes};
ifd.putIFDValue(IFDImageJByteCounts, imageJcounts);
ifd.putIFDValue(IFDImageJInfo, bInfo);
}
(new File(path)).delete(); // Otherwise TiffSaver appends!
TiffSaver tiffSaver = new TiffSaver(path);
tiffSaver.setWritingSequentially(true);
tiffSaver.setLittleEndian(false);
tiffSaver.writeHeader();
// tiffSaver.writeIFD(ifd,0); //* SHould not write here, some fields are calculated during writeImage, that writes IFD too
System.out.println("bytes.length="+bytes.length);
tiffSaver.writeImage(bytes,
ifd,
0, //int no,
0, //int pixelType:INT8, INT16, INT32, UINT8, UINT16, UINT32, FLOAT, BIT, DOUBLE, COMPLEX, DOUBLECOMPLEX; - used to find bpp
true); // boolean last)
}
*/
}
src/main/java/com/elphel/imagej/readers/EyesisTiff.java
View file @
6894dccd
...
...
@@ -57,6 +57,9 @@ import org.w3c.dom.NodeList;
import
org.xml.sax.InputSource
;
import
org.xml.sax.SAXException
;
import
com.elphel.imagej.correction.Eyesis_Correction
;
import
com.elphel.imagej.tileprocessor.QuadCLTCPU
;
//import org.apache.log4j.Logger;
import
ij.IJ
;
...
...
@@ -305,13 +308,42 @@ the type of pixel data in this file getPixelType()
)
throws
IOException
,
FormatException
,
ServiceException
,
DependencyException
{
if
(
imp
.
getType
()==
ImagePlus
.
COLOR_RGB
)
{
// 4*8 bit - type = 0
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"Saving 8-bit TIFF with alpha-channel: "
+
path
);
// is it possible to just add alpha to high bytes?
saveTiffARGB32
(
imp
,
path
,
imageJTags
,
debugLevel
);
ElphelTiffWriter
.
saveTiffARGB32
(
imp
,
path
,
imageJTags
,
debugLevel
);
// saveTiffARGB32(imp, path, imageJTags, debugLevel);
return
;
}
else
if
(
imp
.
getStackSize
()==
4
)
{
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"Saving 32-bit float TIFF with alpha-channel: "
+
path
);
saveTiffARGB
(
imp
,
path
,
mode
,
scale
,
imageJTags
,
debugLevel
);
return
;
}
else
if
(
imp
.
getType
()==
ImagePlus
.
GRAY32
)
{
int
lwir_palette
=
0
;
double
[]
minmax
=
null
;
String
title
=
imp
.
getTitle
();
float
[]
fpixels
=
(
float
[])
imp
.
getProcessor
().
getPixels
();
double
[]
dpixels
=
new
double
[
fpixels
.
length
];
for
(
int
i
=
0
;
i
<
fpixels
.
length
;
i
++)
{
dpixels
[
i
]
=
fpixels
[
i
];
}
ImagePlus
imp_rgb
=
QuadCLTCPU
.
linearStackToColorLWIR
(
Eyesis_Correction
.
CLT_PARAMETERS
,
// clt_parameters, // CLTParameters clt_parameters,
lwir_palette
,
// int lwir_palette, // <0 - do not convert
minmax
,
// minmax, // double [] minmax,
title
,
// String name,
"-rgba"
,
// String suffix, // such as disparity=...
true
,
// boolean toRGB,
new
double
[][]
{
dpixels
},
// faded_textures[nslice], // double [][] texture_data,
imp
.
getWidth
(),
// int width, // int tilesX,
imp
.
getHeight
(),
// int height, // int tilesY,
debugLevel
);
// int debugLevel )
// File test_dump = new File("/home/elphel/Documents/DoD/Ukraine/photos/test/1694531940_120446-02-gps.tiff");
// DumpImageMetadata.processFile(test_dump);
if
(
debugLevel
>
1
)
System
.
out
.
println
(
"Saving 8-bit RGBA TIFF with alpha-channel: "
+
path
);
// is it possible to just add alpha to high bytes?
ElphelTiffWriter
.
saveTiffARGB32
(
imp_rgb
,
path
,
imageJTags
,
debugLevel
);
// saveTiffARGB32(imp_rgb, path, imageJTags, debugLevel);
return
;
}
IJ
.
showMessage
(
"Not yet implemented for this image type"
);
}
...
...
@@ -523,8 +555,8 @@ the type of pixel data in this file getPixelType()
// copy some other data?
ifd
.
putIFDValue
(
IFD
.
COMPRESSION
,
1
);
//TiffCompression.UNCOMPRESSED);
ifd
.
putIFDValue
(
IFD
.
PHOTOMETRIC_INTERPRETATION
,
2
);
// RGB
// ifd.putIFDValue(IFD.EXTRA_SAMPLES,2); // extra
bytes (over 3) meaning Unassociated alpha data
ifd
.
putIFDValue
(
IFD
.
EXTRA_SAMPLES
,
1
);
// extra bytes (over 3) meaning Una
ssociated alpha data
ifd
.
putIFDValue
(
IFD
.
EXTRA_SAMPLES
,
2
);
// extra 2
bytes (over 3) meaning Unassociated alpha data
// ifd.putIFDValue(IFD.EXTRA_SAMPLES,1); // extra 1 byte (over 3) meaning A
ssociated alpha data
ifd
.
putIFDValue
(
IFD
.
SAMPLE_FORMAT
,
1
);
//
// int [] bpsArray={8,8,8,8};
// ifd.putIFDValue(IFD.BITS_PER_SAMPLE, bpsArray); // will be done automatically
...
...
@@ -571,7 +603,6 @@ the type of pixel data in this file getPixelType()
public
static
void
propertiesTiff
(
ImagePlus
imp
){
FileInfo
fi
=
imp
.
getOriginalFileInfo
();
if
((
fi
==
null
)
||(
fi
.
directory
==
null
)
||
(
fi
.
fileFormat
!=
FileInfo
.
TIFF
))
{
...
...
@@ -628,7 +659,15 @@ the type of pixel data in this file getPixelType()
sb
.
append
(
"}"
);
byte
[]
bstring
=
new
byte
[
Array
.
getLength
(
value
)];
for
(
int
i
=
0
;
i
<
bstring
.
length
;
i
++)
bstring
[
i
]=
(
byte
)
Integer
.
parseInt
(
Array
.
get
(
value
,
i
).
toString
());
for
(
int
i
=
0
;
i
<
bstring
.
length
;
i
++)
{
try
{
bstring
[
i
]=
(
byte
)
Integer
.
parseInt
(
Array
.
get
(
value
,
i
).
toString
());
}
catch
(
java
.
lang
.
NumberFormatException
e
)
{
// TODO Auto-generated catch block
// e.printStackTrace();
bstring
[
i
]=(
byte
)
0x3f
;
}
}
// String astring=new String((byte []) value);
String
astring
=
""
;
try
{
...
...
src/main/java/com/elphel/imagej/tileprocessor/QuadCLTCPU.java
View file @
6894dccd
...
...
@@ -9161,80 +9161,90 @@ public class QuadCLTCPU {
// convert to ImageStack of 3 slices
// String [] sliceNames = is_mono? new String[]{"mono"}: new String[]{"red", "blue", "green"};
int
main_color_index
=
is_mono
?
0
:
2
;
double
[][]
rbg_in
=
is_mono
?
new
double
[][]
{
texture_data
[
0
]}
:
new
double
[][]
{
texture_data
[
0
],
texture_data
[
1
],
texture_data
[
2
]};
double
[]
alpha_pixels
=
null
;
// (0..1.0)
if
(
texture_data
.
length
>
rbg_in
.
length
)
{
alpha_pixels
=
texture_data
[
rbg_in
.
length
];
}
if
(!
toRGB
)
{
// Double [][] uses
ImagePlus
imp
;
if
(
alpha_pixels
!=
null
)
{
String
[]
titles
=
{
"Y"
,
"alpha"
};
ImageStack
stack
=
ShowDoubleFloatArrays
.
makeStack
(
new
double
[][]
{
rbg_in
[
0
],
alpha_pixels
},
// iclt_data,
width
,
// (tilesX + 0) * clt_parameters.transform_size,
height
,
// (tilesY + 0) * clt_parameters.transform_size,
titles
,
// or use null to get chn-nn slice names
true
);
// replace NaN with 0.0
imp
=
new
ImagePlus
(
name
+
suffix
,
stack
);
imp
.
getProcessor
().
resetMinAndMax
();
}
else
{
ImageProcessor
ip
=
new
FloatProcessor
(
width
,
height
);
ip
.
setPixels
(
rbg_in
[
0
]);
ip
.
resetMinAndMax
();
imp
=
new
ImagePlus
(
name
+
suffix
,
ip
);
}
return
imp
;
}
String
[]
rgb_titles
=
{
"red"
,
"green"
,
"blue"
};
String
[]
rgba_titles
=
{
"red"
,
"green"
,
"blue"
,
"alpha"
};
String
[]
titles
=
(
alpha_pixels
==
null
)
?
rgb_titles
:
rgba_titles
;
int
num_slices
=
(
alpha_pixels
==
null
)
?
3
:
4
;
double
mn
=
minmax
[
0
];
// colorProcParameters.lwir_low;
double
mx
=
minmax
[
1
];
// colorProcParameters.lwir_high;
ThermalColor
tc
=
new
ThermalColor
(
lwir_palette
,
// colorProcParameters.lwir_palette,
mn
,
mx
,
255.0
);
double
[][]
rgba
=
new
double
[
num_slices
][];
for
(
int
i
=
0
;
i
<
3
;
i
++)
rgba
[
i
]
=
new
double
[
texture_data
[
main_color_index
].
length
];
for
(
int
i
=
0
;
i
<
rbg_in
[
main_color_index
].
length
;
i
++)
{
if
(
i
==
160000
)
{
System
.
out
.
println
(
"i="
+
i
);
}
double
[]
rgb
=
tc
.
getRGB
(
texture_data
[
main_color_index
][
i
]);
rgba
[
0
][
i
]
=
rgb
[
0
];
// red
rgba
[
1
][
i
]
=
rgb
[
1
];
// green
rgba
[
2
][
i
]
=
rgb
[
2
];
// blue
}
if
(
alpha_pixels
!=
null
)
{
rgba
[
3
]
=
alpha_pixels
;
// 0..1
}
ImageStack
stack
=
ShowDoubleFloatArrays
.
makeStack
(
rgba
,
// iclt_data,
width
,
// (tilesX + 0) * clt_parameters.transform_size,
height
,
// (tilesY + 0) * clt_parameters.transform_size,
titles
,
// or use null to get chn-nn slice names
true
);
// replace NaN with 0.0
ImagePlus
imp_rgba
=
EyesisCorrections
.
convertRGBAFloatToRGBA32
(
stack
,
// ImageStack stackFloat, //r,g,b,a
// name+"ARGB"+suffix, // String title,
name
+
suffix
,
// String title,
0.0
,
// double r_min,
255.0
,
// double r_max,
0.0
,
// double g_min,
255.0
,
// double g_max,
0.0
,
// double b_min,
255.0
,
// double b_max,
0.0
,
// double alpha_min,
1.0
);
// double alpha_max)
return
imp_rgba
;
double
[][]
rbg_in
=
is_mono
?
new
double
[][]
{
texture_data
[
0
]}
:
new
double
[][]
{
texture_data
[
0
],
texture_data
[
1
],
texture_data
[
2
]};
double
[]
alpha_pixels
=
null
;
// (0..1.0)
if
(
texture_data
.
length
>
rbg_in
.
length
)
{
alpha_pixels
=
texture_data
[
rbg_in
.
length
];
}
else
{
alpha_pixels
=
new
double
[
texture_data
[
0
].
length
];
for
(
int
i
=
0
;
i
<
alpha_pixels
.
length
;
i
++)
{
alpha_pixels
[
i
]
=
Double
.
isNaN
(
rbg_in
[
0
][
i
])
?
0.0
:
1.0
;
}
}
if
(!
toRGB
)
{
// Double [][] uses
ImagePlus
imp
;
if
(
alpha_pixels
!=
null
)
{
String
[]
titles
=
{
"Y"
,
"alpha"
};
ImageStack
stack
=
ShowDoubleFloatArrays
.
makeStack
(
new
double
[][]
{
rbg_in
[
0
],
alpha_pixels
},
// iclt_data,
width
,
// (tilesX + 0) * clt_parameters.transform_size,
height
,
// (tilesY + 0) * clt_parameters.transform_size,
titles
,
// or use null to get chn-nn slice names
true
);
// replace NaN with 0.0
imp
=
new
ImagePlus
(
name
+
suffix
,
stack
);
imp
.
getProcessor
().
resetMinAndMax
();
}
else
{
ImageProcessor
ip
=
new
FloatProcessor
(
width
,
height
);
ip
.
setPixels
(
rbg_in
[
0
]);
ip
.
resetMinAndMax
();
imp
=
new
ImagePlus
(
name
+
suffix
,
ip
);
}
return
imp
;
}
String
[]
rgb_titles
=
{
"red"
,
"green"
,
"blue"
};
String
[]
rgba_titles
=
{
"red"
,
"green"
,
"blue"
,
"alpha"
};
String
[]
titles
=
(
alpha_pixels
==
null
)
?
rgb_titles
:
rgba_titles
;
int
num_slices
=
(
alpha_pixels
==
null
)
?
3
:
4
;
if
(
minmax
==
null
)
{
minmax
=
new
double
[]
{
Double
.
NaN
,
Double
.
NaN
};
for
(
int
i
=
0
;
i
<
rbg_in
[
0
].
length
;
i
++)
if
(!
Double
.
isNaN
(
rbg_in
[
0
][
i
])){
if
(!(
rbg_in
[
0
][
i
]
>=
minmax
[
0
]))
minmax
[
0
]
=
rbg_in
[
0
][
i
];
if
(!(
rbg_in
[
0
][
i
]
<=
minmax
[
1
]))
minmax
[
1
]
=
rbg_in
[
0
][
i
];
}
}
double
mn
=
minmax
[
0
];
// colorProcParameters.lwir_low;
double
mx
=
minmax
[
1
];
// colorProcParameters.lwir_high;
ThermalColor
tc
=
new
ThermalColor
(
lwir_palette
,
// colorProcParameters.lwir_palette,
mn
,
mx
,
255.0
);
double
[][]
rgba
=
new
double
[
num_slices
][];
for
(
int
i
=
0
;
i
<
3
;
i
++)
rgba
[
i
]
=
new
double
[
texture_data
[
main_color_index
].
length
];
for
(
int
i
=
0
;
i
<
rbg_in
[
main_color_index
].
length
;
i
++)
{
if
(
i
==
160000
)
{
System
.
out
.
println
(
"i="
+
i
);
}
double
[]
rgb
=
tc
.
getRGB
(
texture_data
[
main_color_index
][
i
]);
rgba
[
0
][
i
]
=
rgb
[
0
];
// red
rgba
[
1
][
i
]
=
rgb
[
1
];
// green
rgba
[
2
][
i
]
=
rgb
[
2
];
// blue
}
if
(
alpha_pixels
!=
null
)
{
rgba
[
3
]
=
alpha_pixels
;
// 0..1
}
ImageStack
stack
=
ShowDoubleFloatArrays
.
makeStack
(
rgba
,
// iclt_data,
width
,
// (tilesX + 0) * clt_parameters.transform_size,
height
,
// (tilesY + 0) * clt_parameters.transform_size,
titles
,
// or use null to get chn-nn slice names
true
);
// replace NaN with 0.0
ImagePlus
imp_rgba
=
EyesisCorrections
.
convertRGBAFloatToRGBA32
(
stack
,
// ImageStack stackFloat, //r,g,b,a
// name+"ARGB"+suffix, // String title,
name
+
suffix
,
// String title,
0.0
,
// double r_min,
255.0
,
// double r_max,
0.0
,
// double g_min,
255.0
,
// double g_max,
0.0
,
// double b_min,
255.0
,
// double b_max,
0.0
,
// double alpha_min,
1.0
);
// double alpha_max)
return
imp_rgba
;
}
...
...
@@ -16328,7 +16338,8 @@ public class QuadCLTCPU {
width
,
// int width, // int tilesX,
height
,
// int height, // int tilesY,
debugLevel
);
// int debugLevel )
String
preview_path
=
model_dir
+
Prefs
.
getFileSeparator
()
+
title
+
".jpeg"
;
int
jpeg_q
=
correctionsParameters
.
JPEG_quality
;
String
preview_path
=
model_dir
+
Prefs
.
getFileSeparator
()
+
title
+((
jpeg_q
==
0
)?
".tiff"
:
".jpeg"
);
if
(
new
File
(
preview_path
).
exists
()
&&
!
correctionsParameters
.
thumb_overwrite
)
{
System
.
out
.
println
(
"file "
+
preview_path
+
" exists, skipping preview generation"
);
return
false
;
...
...
@@ -16341,7 +16352,7 @@ public class QuadCLTCPU {
model_dir
,
false
,
false
,
correctionsParameters
.
JPEG_quality
,
// jpegQuality); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
jpeg_q
,
// jpegQuality); // jpegQuality){// <0 - keep current, 0 - force Tiff, >0 use for JPEG
(
debugLevel
>
-
2
)
?
debugLevel
:
1
);
// int debugLevel (print what it saves)
return
true
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment