Java Geotools Tiff Data Fields extract - java

I have Tiff file of population density in the world from Sadac.
I try to read this file in java and extract density number for specific point (LatLon).
I tried opening and reading the file with Geotools, but i dont know, how to extract specific point and its fields (density). I tried many ways but none of them worked.
My code actualy:
File f = new File("/opt/gpw-v4-population-density_2020.tif");
AbstractGridFormat format = GridFormatFinder.findFormat(f);
AbstractGridCoverage2DReader reader = format.getReader(f);
CoordinateReferenceSystem crs = reader.getCoordinateReferenceSystem();
System.out.println(crs);
GridCoverage2D cov = null;
try {
cov = reader.read(null);
} catch (Exception e) {
//todo
}
Can anyone advise me how to get to the point and its fields?
Thank you for advice.

Resolved.
private static GridCoverage2D grid;
private static Raster gridData;
private static void initTif() throws Exception {
File tiffFile = new File("/opt/gpw-v4-population-density_2020.tif");
GeoTiffReader reader = new GeoTiffReader(tiffFile);
grid = reader.read(null);
RenderedImage image = grid.getRenderedImage();
if (image != null) {
gridData = image.getData();
}
}
public void getDensity(double x, double y) throws InvalidGridGeometryException, TransformException {
GridGeometry2D gg = grid.getGridGeometry();
DirectPosition2D posWorld = new DirectPosition2D(x, y);
GridCoordinates2D posGrid = gg.worldToGrid(posWorld);
double[] pixel = new double[1];
double[] data = gridData.getPixel(posGrid.x, posGrid.y, pixel);
for (double d : data) {
System.out.println(d);
}
}

Related

OpenCV on Android: net.forward yields "215 Assertion failed"

Following this tutorial from openCV, and it should be straight forward. However, it crashes with an assertion fail on the net.forward, that I cannot resolve/find anywhere else.
Thought this problem seemed similar and tried to go through the fix/problem finding. However, restarting the discussion and trials showed it is likely not the same. I used initially 3.4.3, which did not support the same Mat type somehow. Updated to 3.4.7 now, and can confirm the blob size is okay (generated from image). Tried also various other prototxt and caffemodels, but doubt by now that the problem lies there (works if the files are okay, otherwise the net loading fails). The key code should be this:
// Load a network.
public void onCameraViewStarted(int width, int height) {
String proto = getPath("deploy.prototxt", this);
String weights = getPath("MobileNetSSD_deploy.caffemodel", this);
net = Dnn.readNetFromCaffe(proto, weights);
Log.i(TAG, "Network loaded successfully");
}
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
// Get a new frame
Mat frame = inputFrame.rgba();
Imgproc.cvtColor(frame, frame, Imgproc.COLOR_RGBA2RGB);
// Forward image through network.
Mat blob = Dnn.blobFromImage(frame, 0.007843,
new Size(300, 300),
new Scalar(127.5, 127.5, 127.5));
net.setInput(blob);
Mat detections = net.forward(); //***215 ASSERTION FAILED occurs***
int cols = frame.cols();
int rows = frame.rows();
detections = detections.reshape(1, (int)detections.total() / 7);
for (int i = 0; i < detections.rows(); ++i) {
double confidence = detections.get(i, 2)[0];
if (confidence > 0.2) {
int classId = (int)detections.get(i, 1)[0];
int left = (int)(detections.get(i, 3)[0] * cols);
int top = (int)(detections.get(i, 4)[0] * rows);
int right = (int)(detections.get(i, 5)[0] * cols);
int bottom = (int)(detections.get(i, 6)[0] * rows);
// Draw rectangle around detected object.
Imgproc.rectangle(frame, new Point(left, top), new Point(right, bottom),
new Scalar(0, 255, 0));
String label = classNames[classId] + ": " + confidence;
int[] baseLine = new int[1];
Size labelSize = Imgproc.getTextSize(label, Core.FONT_HERSHEY_SIMPLEX, 0.5, 1, baseLine);
// Draw background for label.
Imgproc.rectangle(frame, new Point(left, top - labelSize.height),
new Point(left + labelSize.width, top + baseLine[0]),
new Scalar(255, 255, 255), Core.FILLED);
// Write class name and confidence.
Imgproc.putText(frame, label, new Point(left, top),
Core.FONT_HERSHEY_SIMPLEX, 0.5, new Scalar(0, 0, 0));
}
}
return frame;
}
public void onCameraViewStopped() {}
// Upload file to storage and return a path.
private static String getPath(String file, Context context) {
AssetManager assetManager = context.getAssets();
BufferedInputStream inputStream = null;
try {
// Read data from assets.
inputStream = new BufferedInputStream(assetManager.open(file));
byte[] data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
// Create copy file in storage.
File outFile = new File(context.getFilesDir(), file);
FileOutputStream os = new FileOutputStream(outFile);
os.write(data);
os.close();
// Return a path to file which may be read in common way.
return outFile.getAbsolutePath();
} catch (IOException ex) {
Log.i(TAG, "Failed to upload a file");
}
return "";
}
The full error message is
cv::Exception: OpenCV(3.4.7) /build/3_4_pack-android/opencv/modules/dnn/src/layers/batch_norm_layer.cpp:39: error: (-215:Assertion failed) blobs.size() >= 2 in function 'cv::dnn::BatchNormLayerImpl::BatchNormLayerImpl(const cv::dnn::experimental_dnn_34_v13::LayerParams&)'
I expect it to not crash. The frame should be okay (image loaded), the net is not empty, and the layers in the net seem fine too (checked since there are some differences using caffe in java). Any help is appreciated!
After some days of research in different directions, I found the problem: the frame format should be BGR, not RGB! That means
Imgproc.cvtColor(frame, frame, Imgproc.COLOR_RGBA2BGR);

Convert CCITT Group 3 1-Dimensional TIFF to PDF using iText in Java

I am experiencing an EOF Exception as follows when attempting to read tiff files using iText 5.5.10
ExceptionConverter: java.io.EOFException
at com.itextpdf.text.pdf.RandomAccessFileOrArray.readFully(RandomAccessFileOrArray.java:249)
at com.itextpdf.text.pdf.RandomAccessFileOrArray.readFully(RandomAccessFileOrArray.java:241)
at com.itextpdf.text.pdf.codec.TiffImage.getTiffImage(TiffImage.java:209)
at com.itextpdf.text.pdf.codec.TiffImage.getTiffImage(TiffImage.java:314)
at com.itextpdf.text.pdf.codec.TiffImage.getTiffImage(TiffImage.java:302)
at com.itextpdf.text.Image.getInstance(Image.java:428)
at com.itextpdf.text.Image.getInstance(Image.java:374)
at TiffToPdf.main(TiffToPdf.java:137)
The code I am using is:
byte[] data = null;
Image img = null;
try {
data = Files.readAllBytes(Paths.get("tiff.tif"));
img = Image.getInstance(data, true);
}
catch (Exception e) {
e.printStackTrace();
}
I have tried skipping the Image step and using the TiffImage class explicitly but I experience the same error.
byte[] data = null;
Image img = null;
try {
data = Files.readAllBytes(Paths.get("tiff.tif"));
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
RandomAccessSource fileBytes = factory.createSource(data);
RandomAccessFileOrArray s = new RandomAccessFileOrArray(fileBytes);
img = TiffImage.getTiffImage(s, true, 1, true);
}
catch (Exception e) {
e.printStackTrace();
}
I noticed that there are 2 classes within iText called TIFFFaxDecompressor and TIFFFaxDecoder but I haven't been able to find any resources online on how to use them.
with your given tiff image, the following code does worked for me i.e., converted to pdf successfully.
byte[] data = null;
com.itextpdf.text.Image img = null;
try {
//System.out.println(Paths.get("src/main/resources/tiff.tif"));
data = Files.readAllBytes(Paths.get("src/main/resources/file.tif"));
RandomAccessSourceFactory factory = new RandomAccessSourceFactory();
RandomAccessSource fileBytes = factory.createSource(data);
RandomAccessFileOrArray s = new RandomAccessFileOrArray(fileBytes);
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("src/main/resources/destination.pdf"));
document.open();
int pages = TiffImage.getNumberOfPages(s);
Image image;
for (int i = 1; i <= pages; i++) {
image = TiffImage.getTiffImage(s, i);
Rectangle pageSize = new Rectangle(image.getWidth(),
image.getHeight());
document.setPageSize(pageSize);
document.newPage();
document.add(image);
}
document.close();
} catch (Exception e) {
e.printStackTrace();
}

Automatically capture clip board data and save it into a file

Capture a image from the clipboard whenever Print screen is pressed and save it in a file (.doc) using java
Main aim is to copy the data from the clipboard and automatically save it into local disk without going to the desired program (i.e MS Word)- click new - pressing (Ctrl+V) to paste and save it with a name.
The code should perform all of the above three steps automatically.
My Source Code
public class CaptureScreenShot {
private static String DIR ="C:\\QUIS\\";
private static JTextField txtDocNumber;
public static void main(String[] args) throws Exception{
txtDocNumber = new JTextField();
Robot robot = new Robot();
Dimension d = new Dimension(Toolkit.getDefaultToolkit().getScreenSize());
int width = (int) d.getWidth();
int height = (int) d.getHeight();
robot.delay(5000);
Image image = robot.createScreenCapture(new Rectangle(0, 0, width,
height));
BufferedImage bi = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.createGraphics();
g.drawImage(image, 0, 0, width, height, null);
String fileNameToSaveTo = "C:/QUIS/screenCapture_" + createTimeStampStr() + ".PNG";
String newFile = "C:/QUIS/x" + ".org";
File newFilee = new File(newFile);
writeImage(bi, fileNameToSaveTo, "PNG");
System.out.println("Screen Captured Successfully and Saved to:\n"+fileNameToSaveTo);
Desktop desktop = Desktop.getDesktop();
writeImage(bi, newFile, "org");
desktop.open(newFilee);
}
public static int writeImage(BufferedImage img, String fileLocation,
String extension) {
try {
BufferedImage bi = img;
File outputfile = new File(fileLocation);
ImageIO.write(bi, extension, outputfile);
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
public static String createTimeStampStr() throws Exception {
Calendar mycalendar = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd_hhmmss");
String timeStamp = formatter.format(mycalendar.getTime());
return timeStamp;
}
}
If you are not particular about a java code, you could use some screen capture tool instead. Snagit is a good tool. You could find it on http://www.techsmith.com/snagit.html
Try this sample code, according to your question it will copy contents from clipboard and will generate image file
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
try {
//Get data from clipboard and assign it to an image.
//clipboard.getData() returns an object, so we need to cast it to a BufferdImage.
BufferedImage image = (BufferedImage)clipboard.getData(DataFlavor.imageFlavor);
//file that we'll save to disk.
File file = new File("image.jpg");
//class to write image to disk. You specify the image to be saved, its type,
// and then the file in which to write the image data.
ImageIO.write(image, "jpg", file);
}

Java heap space error/ Out of memory error

I'm getting heap space error/ out of memory exception.
I'm trying to generate a PDF using iText and converting the PDF to jpg image using aspose api. The PDF which is being generated is of 3 pages, I'm converting that PDF to image page by page and stitching them together into one jpg image. This code is working fine in my local development machine, but getting exception when move to test server.
The code which I'm using for this is:
public void silSignedPDF(AgreementBean agBean,String sourceTemplatePDFURL, Hashtable<String, String> val, String destinationPDFPath) throws IOException, DocumentException, SQLException{
String methodName = "silSignedPDF";
LogTracer.writeDebugLog(className, methodName, "Start");
String serverPath = System.getProperty("jboss.server.home.dir");
String sourceTemplatePDFURL1 = serverPath+AppConstants.PDL_Agreement_Template +"/Online_Installment_Agreement.pdf";
System.out.println("sourceTemplatePDFURL1 "+sourceTemplatePDFURL1);
File f = new File(sourceTemplatePDFURL1);
InputStream sourceTemplatePDFUrlStream = new BufferedInputStream(new FileInputStream(f));
File destinationFile = new File(destinationPDFPath+"/"+agBean.getDealNbr()+".pdf");
PdfReader reader = new PdfReader(sourceTemplatePDFUrlStream);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
destinationFile));
AcroFields form = stamper.getAcroFields();
Enumeration enumeration = val.keys();
// iterate through Hashtable val keys Enumeration
while (enumeration.hasMoreElements()) {
String nextElement = (String) enumeration.nextElement();
String nextElementValue = (String) val.get(nextElement);
form.setField(nextElement, nextElementValue);
}
stamper.setFormFlattening(true);
stamper.close();
PdfConverter pdf = new PdfConverter();
pdf.bindPdf(destinationPDFPath+"/"+agBean.getDealNbr()+".pdf");
try {
pdf.doConvert();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//set start and end pages
pdf.setStartPage(1);
pdf.setEndPage(1);
//initialize conversion process
//convert pages to images
String suffix = ".jpg";
int imageCount = 1;
while (pdf.hasNextImage())
{
try {
pdf.getNextImage(destinationPDFPath+"/"+agBean.getDealNbr()+"_"+imageCount + suffix,ImageType.JPEG);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
imageCount++;
}
/* PDFImages pdfDoc = new PDFImages (destinationPDFPath+"/"+agBean.getDealNbr()+".pdf", null);
for (int count = 0; count < pdfDoc.getPageCount(); ++count)
{
pdfDoc.savePageAsJPEG(count,destinationPDFPath+"/"+agBean.getDealNbr()+"_"+count + ".png", 150, 0.8f);
}*/
File file1 = new File(destinationPDFPath+"/"+agBean.getDealNbr()+"_1" + ".jpg");
File file2 = new File(destinationPDFPath+"/"+agBean.getDealNbr()+"_2" + ".jpg");
File file3 = new File(destinationPDFPath+"/"+agBean.getDealNbr()+"_3" + ".jpg");
BufferedImage img1 = ImageIO.read(file1);
BufferedImage img2 = ImageIO.read(file2);
BufferedImage img3 = ImageIO.read(file3);
int widthImg1 = img1.getWidth();
int heightImg1 = img1.getHeight();
int heightImg2 = img2.getHeight();
int heightImg3 = img3.getHeight();
BufferedImage img = new BufferedImage(
widthImg1,
heightImg1+heightImg2+heightImg3,
BufferedImage.TYPE_INT_RGB);
img.createGraphics().drawImage(img1, 0, 0, null);
img.createGraphics().drawImage(img2, 0, heightImg1, null);
img.createGraphics().drawImage(img3, 0, heightImg1+heightImg2, null);
File final_image = new File(destinationPDFPath+"/"+agBean.getDealNbr() + ".jpg");
ImageIO.write(img, "png", final_image);
file1.delete();
file2.delete();
file3.delete();
LogTracer.writeDebugLog(className, methodName, "End");
}
Heap size should be changed for your JVM, but dont change it to any random number. Heap size should be modified based on the memory that is used by your system. You can check this for further specification.
Page to Image conversion using Aspose.Pdf required more memory than the default. Run the program with at least 512 MB memory (-Xmx512m).

Poor Image Quality when using SVGConverter in Batik to convert svg to png

My converted image's quality is very low. I have tried using the setQuality method but it does not seem to change anything.
This is the part of the code that converts svg to png:
SVGConverter svgConverter = new SVGConverter();
String[] sources = { "C:/imageData.svg" };
svgConverter.setSources(sources);
svgConverter.setDestinationType(DestinationType.PNG);
svgConverter.setDst(new File("C:/image.png"));
Does anyone know how I could make the image quality better?
I use this code when converting SVG to PNG (using byte arrays):
private byte[] renderPng(byte[] svgBytes) {
try {
TranscoderInput transcoderInput = new TranscoderInput(new ByteArrayInputStream(svgBytes));
ByteArrayOutputStream output = new ByteArrayOutputStream();
TranscoderOutput transcoderOutput = new TranscoderOutput(output);
Transcoder transcoder = null;
String type = "png";
if(type.equalsIgnoreCase("png")) {
transcoder = new PNGTranscoder()
{
#Override
protected ImageRenderer createRenderer()
{
ImageRenderer r = super.createRenderer();
RenderingHints rh = r.getRenderingHints();
rh.add(new RenderingHints(RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY));
rh.add(new RenderingHints(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC));
rh.add(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON));
rh.add(new RenderingHints(RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.VALUE_COLOR_RENDER_QUALITY));
rh.add(new RenderingHints(RenderingHints.KEY_DITHERING,
RenderingHints.VALUE_DITHER_DISABLE));
rh.add(new RenderingHints(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY));
rh.add(new RenderingHints(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE));
rh.add(new RenderingHints(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON));
rh.add(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF));
r.setRenderingHints(rh);
return r;
}
};
transcoder.addTranscodingHint(PNGTranscoder.KEY_BACKGROUND_COLOR, Color.WHITE);
} else {
transcoder = new JPEGTranscoder();
Float jpegQuality = new Float(0.95);
// KEY_WIDTH - seems to pick it up just fine from the SVG charts. Set to 560 otherwise.
// KEY_QUALITY 0-1.0 with 1.0 being No Loss. Value must be of type Float. 0.95 is 30% smaller and looks great.
transcoder.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, jpegQuality);
}
// NOTE: for linux you need Java 1.4.1+ AND the headless environment (e.g. export JAVA_OPTS='-Djava.awt.headless=true').
try {
transcoder.transcode(transcoderInput, transcoderOutput);
}
catch(Exception e) {
logger.error("SVG To Raster response transcode exception", e);
if(output != null) {
output.close();
}
throw( new RuntimeException("SVG To Raster Filter Response Stream Exception", e) );
}
if(output != null) {
output.flush();
output.close();
}
transcoderInput = null;
transcoderOutput = null;
transcoder = null;
return output.toByteArray();
} catch (Exception exc) {
logger.error("Error in rendering png method", exc);
}
return new byte[0];
}
Also, your clipPath elements in your SVG documents should contain this attribute, otherwise it will have strange artifacts:
<clipPath shape-rendering="geometricPrecision" ... >
In Apache Batik, you can change resolution by passing Transcoder hint KEY_PIXEL_UNIT_TO_MILLIMETER.
However the important aspect is that you need to scale your height & width to same scale as the new resolution you are seeking.
For example:
my SVG has 3.5 * 2.0 Inches (252 * 144 Pixels) size.
Target resolution is 600 DPI.
int RESOLUTION_DPI = 600;
float SCALE_BY_RESOLUTION = RESOLUTION_DPI / 72f;
float scaledWidth = 252*SCALE_BY_RESOLUTION;
float scaledHeight = 144*SCALE_BY_RESOLUTION;
float pixelUnitToMM = new Float(25.4f/RESOLUTION_DPI);
transcoderInput = new TranscoderInput(svgDocument);
TranscoderOutput transcoderOutput = new TranscoderOutput(ostream);
transcoder.addTranscodingHint(ImageTranscoder.KEY_BACKGROUND_COLOR, Color.WHITE);
transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, scaledWidth);
transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, scaledHeight);
transcoder.addTranscodingHint(PNGTranscoder.KEY_PIXEL_UNIT_TO_MILLIMETER, pixelUnitToMM);
transcoder.transcode(transcoderInput, transcoderOutput);
Try this....
jpeg.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, new Float(keyQuality));
jpeg.addTranscodingHint(JPEGTranscoder.KEY_HEIGHT, height*scalePercentage);
jpeg.addTranscodingHint(JPEGTranscoder.KEY_WIDTH, width*scalePercentage);
jpeg.addTranscodingHint(JPEGTranscoder.KEY_QUALITY, 1.0f);
jpeg.addTranscodingHint(JPEGTranscoder.KEY_BACKGROUND_COLOR, Color.WHITE);
You need to increase the height and width like
set keyQuality 1.0f.
If height=200 increase height by 200*3(height*scalePercentage). Similar to width also

Categories

Resources