I have the following method
private void passStingR(StringBuilder retVal) throws BadLocationException, Exception {
int getinitialscrollpos;
getinitialscrollpos = getinitialscrollPosition(scrollMEL);
//1. get chartPanel Bounds
Rectangle2D xy = chartPanel.getScreenDataArea();
Rectangle bounds = chartPanel.getBounds();
int horz = (int) bounds.getX();//need to get the correct x and y
int vertz = (int) bounds.getY();
int width1 = (int) bounds.getWidth();
int height1 = (int) bounds.getHeight();
System.out.println(horz + " " + vertz + " " + width1 + " " +height1);//get positioning data
/////////////////////////////////
Document docR = null;
docR = loadXMLFromString(retVal.toString());//pull in the XML data into a new doc
populate1R(docR);
tableMEL.getTableHeader().setReorderingAllowed(false);//prevent user from changing column order now at refresh level
SimpleDateFormat time_formatterR = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String current_time_strR = time_formatterR.format(System.currentTimeMillis());
updatetFieldDG.setText(current_time_strR);
middlePanel.add(scrollMEL);
scrollMEL.getVerticalScrollBar().setValue(getinitialscrollpos);
System.out.println("End" + getinitialscrollpos);
getTableData(tableMEL);
head(tableMEL);
createGraphGUI();
//2.the problem lies here as i would expect the chartPanel.setBounds to restore the position that i got at 1.
chartPanel.setBounds(horz,vertz,width1,height1);//xywidthheight
System.out.println(chartPanel.getBounds());//set the positioning items as per the start
////////////
}
The issue is that when my data is refreshed i lose the zoom positioning.
I have therefore tried to get the chartPanel bounds at the start of the method and then try to apply it at the end of the method - however the zoom positioning just keeps on reverting back to the default position which is just the whole graph. Please can someone help?
I worked this out:
private void passStingR(StringBuilder retVal) throws BadLocationException, Exception {
int getinitialscrollpos;
getinitialscrollpos = getinitialscrollPosition(scrollMEL);
try {
CategoryPlot plot = (CategoryPlot) chartPanel.getChart().getPlot();//get plot of graph
//System.out.print("Plot Type" + plot);
ValueAxis rangeAxis = plot.getRangeAxis();//get range of axis of graph
System.out.print("Range " + rangeAxis);//get range lower and upper as an array
map.put(1, rangeAxis);
} catch (Exception e) {
System.out.print("Error has occured");
} finally {
////refresh data////
Document docR = null;
docR = loadXMLFromString(retVal.toString());//pull in the XML data into a new doc
populate1R(docR);
tableMEL.getTableHeader().setReorderingAllowed(false);//prevent user from changing column order now at refresh level
SimpleDateFormat time_formatterR = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String current_time_strR = time_formatterR.format(System.currentTimeMillis());
updatetFieldDG.setText(current_time_strR);
middlePanel.add(scrollMEL);
scrollMEL.getVerticalScrollBar().setValue(getinitialscrollpos);
System.out.println("End" + getinitialscrollpos);
getTableData(tableMEL);
head(tableMEL);
createGraphGUI();
if (map.get(1) != null) {
System.out.print("get map" + map.get(1));
CategoryPlot plot = (CategoryPlot) chartPanel.getChart().getPlot();
plot.setRangeAxis(map.get(1));//get range of axis of graph
}
}
}
Related
I have a table called IK_TEMP and it contains columns called data, range .
String sql = "SELECT DATA, RANGE FROM IK_TEMP";
try (Connection conn = this.connect();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)){
// loop through the result set
while (rs.next()) {
System.out.println(rs.getString("DATA") + "\t" +
rs.getBytes("RANGE"));
fromBytes(rs.getBytes("RANGE"));
}
The RANGE field(binary / BLOB) field is already encoded using binary from arcGIS and saved in the Database.
http://www.geopackage.org/spec120/#gpb_format
I want to decode this RANGE field using java.
Here I have tried with fromBytes method
public void fromBytes(byte[] bytes) {
this.bytes = bytes;
ByteReader reader = new ByteReader(bytes);
// Get 2 bytes as the magic number and validate
String magic = null;
try {
magic = reader.readString(2);
} catch (UnsupportedEncodingException e) {
throw new GeoPackageException(
"Unexpected GeoPackage Geometry magic number character encoding: Expected: "
+ GeoPackageConstants.GEOMETRY_MAGIC_NUMBER);
}
if (!magic
.equals(GeoPackageConstants.GEOMETRY_MAGIC_NUMBER)) {
throw new GeoPackageException(
"Unexpected GeoPackage Geometry magic number: "
+ magic
+ ", Expected: "
+ GeoPackageConstants.GEOMETRY_MAGIC_NUMBER);
}
// Get a byte as the version and validate, value of 0 = version 1
byte version = reader.readByte();
if (version != GeoPackageConstants.GEOMETRY_VERSION_1) {
throw new GeoPackageException(
"Unexpected GeoPackage Geometry version: "
+ version
+ ", Expected: "
+ GeoPackageConstants.GEOMETRY_VERSION_1);
}
// Get a flags byte and then read the flag values
byte flags = reader.readByte();
int envelopeIndicator = readFlags(flags);
reader.setByteOrder(byteOrder);
// Read the 5th - 8th bytes as the srs id
srsId = reader.readInt();
// Read the envelope
envelope = readEnvelope(envelopeIndicator, reader);
// Save off where the WKB bytes start
wkbGeometryIndex = reader.getNextByte();
// Read the Well-Known Binary Geometry if not marked as empty
if (!empty) {
geometry = GeometryReader.readGeometry(reader);
}
}
I am getting x and y coordinates and geometryType in geometry object, But how can I get lat and long from this
In one of the example they have given in JS reff.
for item in (GeometryDataXYValue)!{
let xValue = item.paths?.ofX
let yValue = item.paths?.ofY
//recieve x y point
currentPoint = AGSPoint(x: xValue!, y: yValue!, spatialReference: AGSSpatialReference.webMercator())
//convert to lat long by AGSSpatialReference.wgs84()
if let aReference = AGSGeometryEngine.projectGeometry(currentPoint!, to: AGSSpatialReference.wgs84()) as? AGSPoint {
currentPoint = aReference
}
}
var long:Double = currentPoint!.x
var lat: Double = currentPoint!.y
print("value long lat = \(long , lat)")
}
But I want the same conversion in java.
This is another example
example
Please try the following methods to obtain data:
Blob picture = resultSet.getBlob("RANGE");
inputStream = picture.getBinaryStream();
outputStream = new FileOutputStream("D:\\blob\\RANGE.jpg");
byte[] bufferBytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bufferBytes)) != -1) {
outputStream.write(bufferBytes, 0, len);
}
You can get the lat and long by using the geotools library.
Coordinate coordinate = new Coordinate(geometry.getEnvelope().getMaxX(), geometry.getEnvelope().getMaxY());
MathTransform transform;
Coordinate targetGeometry;
double latitude;
double longitude;
try {
//sourceCRS is to convert the X and Y coordinates to lat long
CoordinateReferenceSystem sourceCRS = CRS.decode("EPSG:25832");
CoordinateReferenceSystem targetCRS = CRS.decode("EPSG:4326");
transform = CRS.findMathTransform(sourceCRS, targetCRS, false);
targetGeometry = JTS.transform(coordinate, coordinate, transform);
latitude = targetGeometry.getX();
longitude = targetGeometry.getY();
} catch (FactoryException | TransformException e) {
e.printStackTrace();
}
}
I am running template matching using openCV 3.4.7 Android SDK (java).
The code work almost perfectly; when the template is match, it draws a rectangle on the matching area. The problem is that even when there is no match, it draws a random rectangle. I think that happens because the threshold is not set correctly. If so, can someone please help me out?
Here's the code:
public static void run(String inFile, String templateFile, String outFile,
int match_method) {
Mat img = Imgcodecs.imread(inFile);
Mat templ = Imgcodecs.imread(templateFile);
// / Create the result matrix
int result_cols = img.cols() - templ.cols() + 1;
int result_rows = img.rows() - templ.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
// / Do the Matching and Normalize
Imgproc.matchTemplate(img, templ, result, match_method);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
// / Localizing the best match with minMaxLoc
Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
Point matchLoc;
if (match_method == Imgproc.TM_SQDIFF
|| match_method == Imgproc.TM_SQDIFF_NORMED) {
matchLoc = mmr.minLoc;
} else {
matchLoc = mmr.maxLoc;
}
// / Show me what you got
Imgproc.rectangle(img, matchLoc, new Point(matchLoc.x + templ.cols(),
matchLoc.y + templ.rows()), new Scalar(0, 0, 128));
// Save the visualized detection.
System.out.println("Writing " + outFile);
Imgcodecs.imwrite(outFile, img);
}
You can use Imgproc.TM_CCOEFF_NORMED or Imgproc.TM_CCORR_NORMED and mmr.maxVal >= 0.8. It should take care of most of your false positives.
Sample Code:
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import java.io.File;
import java.nio.file.Files;
public class templateMatchingTester {
private static String str = null;
static {
if (str == null) {
str = "initialised";
nu.pattern.OpenCV.loadShared();
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
}
private static Mat createMatrixFromImage(String imagePath) {
Mat imageMatrix = Imgcodecs.imread(imagePath);
Mat greyImage = new Mat();
Imgproc.cvtColor(imageMatrix, greyImage, Imgproc.COLOR_BGR2GRAY);
return greyImage;
}
private static boolean matchTemplate(String pathToInputImage,String pathToTemplate){
Mat inputImage = createMatrixFromImage(pathToInputImage);
Mat templateImage = createMatrixFromImage(pathToTemplate);
// Create the result matrix
int result_cols = inputImage.cols() - templateImage.cols() + 1;
int result_rows = inputImage.rows() - templateImage.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_8UC1);
int match_method;
match_method = Imgproc.TM_CCOEFF_NORMED;//Imgproc.TM_CCORR_NORMED;
Imgproc.matchTemplate(inputImage, templateImage, result, match_method);
Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
double minMatchQuality = 0.85;
System.out.println(mmr.maxVal);
if (mmr.maxVal >= minMatchQuality){
return true;
} else
return false;
}
public static void main(String args[]) {
String template = "path/to/your/templateImage";
final File folder = new File("path/to/your/testImagesFolder/");
int matchCount = 0;
for (final File fileEntry : folder.listFiles()){
if (matchTemplate(fileEntry.getPath(),template)){
matchCount+=1;
}else
System.out.println(fileEntry.getPath());
}
System.out.println(matchCount);
}
}
Use a normed match method to ensure your match value is [0..1].
Replace this line
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
with a thresholding operation. Otherwise a best match of 0.9 would become 1 by the second normalization and you would lose the actual match "quality" information.
Normalizing the result of the template matching will always result in your best match being 1 making it impossible to discard a bad match.
i wrote an app that would take a screenshot of the game overwatch and attempt to tell who is on each team. using template matching and open cv. project need to iterate over the result image and check values.
OpenCVUtils.getPointsFromMatAboveThreshold(result,
0.90f)
public static void scaleAndCheckAll(String guid){
Mat source = imread(IMG_PROC_PATH + guid); //load the source image
Mat scaledSrc = new Mat(defaultScreenshotSize, source.type());
resize(source, scaledSrc, defaultScreenshotSize);
Mat sourceGrey = new Mat(scaledSrc.size(), CV_8UC1);
cvtColor(scaledSrc, sourceGrey, COLOR_BGR2GRAY);
for (String hero : getCharacters()) {
Mat template = OpenCVUtils.matFromJar(TEMPLATES_FOLDER + hero + ".png", 0); //load a template
Size size = new Size(sourceGrey.cols()-template.cols()+1, sourceGrey.rows()-template.rows()+1);
Mat result = new Mat(size, CV_32FC1);
matchTemplate(sourceGrey, template, result, TM_CCORR_NORMED);// get results
Scalar color = OpenCVUtils.randColor();
List<Point> points = OpenCVUtils.getPointsFromMatAboveThreshold(result,
0.90f);
for (Point point : points) {
//rectangle(scaledSrc, new Rect(point.x(),point.y(),template.cols(),template.rows()), color, -2, 0, 0);
putText(scaledSrc, hero, point, FONT_HERSHEY_PLAIN, 2, color);
}
}
String withExt = IMG_PROC_PATH + guid +".png";
imwrite(withExt, scaledSrc);
File noExt = new File(IMG_PROC_PATH + guid);
File ext = new File(withExt);
noExt.delete();
ext.renameTo(noExt);
}
the other method.
public static List<Point> getPointsFromMatAboveThreshold(Mat m, float t){
List<Point> matches = new ArrayList<Point>();
FloatIndexer indexer = m.createIndexer();
for (int y = 0; y < m.rows(); y++) {
for (int x = 0; x < m.cols(); x++) {
if (indexer.get(y,x)>t) {
System.out.println("(" + x + "," + y +") = "+ indexer.get(y,x));
matches.add(new Point(x, y));
}
}
}
return matches;
}
you can just get the first from the list or see how close they are if you expect multiple matches.
i have problem with remove data from line chart. I wrote a program drawing graphs that after the action click on the button completes the chart data.
dataSeries1.getData().removeAll(); <- doesn't work.
Code:
NumberAxis xAxis = new NumberAxis();
xAxis.setLabel("Oś Y");
NumberAxis yAxis = new NumberAxis();
yAxis.setLabel("Oś X");
final LineChart lineChart = new LineChart(xAxis, yAxis);
final XYChart.Series dataSeries1 = new XYChart.Series();
lineChart.setCreateSymbols(false);
lineChart.getData().add(dataSeries1);
Button action:
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
int lewy = Integer.parseInt(kresLewy.getText());
int prawy = Integer.parseInt(kresPrawy.getText());
String rownanie = field.getText();
try {
String tekst = lewy + "; " + prawy + "; " + rownanie;
StringReader tekstReader = new StringReader(tekst);
parsery.interpreter.parser parser_obj
= new parsery.interpreter.parser(new parsery.interpreter.MyLexer(tekstReader));
Object result = parser_obj.parse().value;
String sWynik = result.toString();
ZmiennaX zX = new ZmiennaX();
ArrayList<Double> xArr = new ArrayList<Double>();
for (double i = lewy; i <= prawy + 0.001; i = i + zX.getDokladnosc()) // +0.001 dla bledow zaokraglenia
{
xArr.add(zX.round2(i));
}
String sX = xArr.toString();
String wartosciX = sX.substring(1, sX.length() - 1);
String wartosciY = sWynik.substring(1, sWynik.length() - 1);
String XbezSpacji = wartosciX.replace(" ", "");
String YbezSpacji = wartosciY.replace(" ", "");
String[] splitX = XbezSpacji.split(",");
String[] splitY = YbezSpacji.split(",");
dataSeries1.getData().removeAll();
for(int i=0; i<splitX.length; i++){
double x = Double.parseDouble(splitX[i]);
double y = Double.parseDouble(splitY[i]);
dataSeries1.getData().add(new XYChart.Data(x, y));
}
} catch (Exception e) {
System.out.println("Podczs obliczenia wystapil blad. (" + e.getMessage() + ")");
} catch (Error error) {
System.out.println("Podczs obliczenia wystapil blad. (" + error.getMessage() + ")");
}
}
});
Can anyone help me to remove data after drawing a new chart?
removeAll requires elements to be removed passed in its parameter. Since you provided none - nothing gets removed:
dataSeries1.getData().removeAll();
You want to use clear() instead in the line above.
public void clear()
Removes all of the elements from this list (optional operation). The list will be empty after this call returns.
You can use Collections.singleton to remove all data:
dataSeries1.getData().removeAll(Collections.singleton(barChart.getData().setAll()));
See Oracle documentation for Collections.singleton https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html
I am trying to create an image with a given text and style. eg;
" textStyle(Offer ends 25/12/2016. Exclusions Apply., disclaimer) textStyle(See Details,underline) "
In above line i am splitting and creating a map that stores the first parameter of textStyle block as key and second parameter as value where second param defines the style to be applied on first param. Hence an entry of map will look like .
Now when i iterate over this map to write the text to image i check if the text is overflowing the width. If yes then it breaks the text and adds it to next line in the horizontal center. So for example lets say i am trying to write "Offer ends 25/12/2016. Exclusions Apply." with Arial and font size 12. While writing i find that i can write till "Offer ends 23/12/2016. " only and "Exclusions apply" has to go in next line. But it writes the text in horizontal center neglecting that as there is space left horizontally i can write "See Details" too in the same line.
Please help. Below is the code what i have tried. I have also tried creating a JTextPane and then converting it to image but this cannot be an option as it first creates the frame, makes it visible, writes it and then disposes it. And most of the times i was getting Nullpointer exception on SwingUtilities.invokeAndWait.
Actual : http://imgur.com/7aIlcEQ
Expected http://imgur.com/038zQTZ
public static BufferedImage getTextImage(String textWithoutStyle, Map<String, String> textToThemeMap, Properties prop, int height, int width) {
BufferedImage img = new BufferedImage(width,height,BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2d = img.createGraphics();
g2d.setPaint(Color.WHITE);
FontMetrics fm = g2d.getFontMetrics();
Map<String, Font> textToFontMap = new LinkedHashMap<String, Font>();
for(Map.Entry<String, String> entry : textToThemeMap.entrySet()) {
if(StringUtils.isNotBlank(entry.getKey()) && StringUtils.isNotBlank(entry.getValue())) {
Font font = getFont(prop, entry.getValue().trim());
g2d.setFont(font);
fm = g2d.getFontMetrics();
String string = entry.getKey();
char[] chars = null;
int i = 0, pixelWidth = 0;
List<String> newTextList = new ArrayList<String>();
if(fm.stringWidth(string) > (width - 10)) {
chars = string.toCharArray();
for (i = 0; i < chars.length; i++) {
pixelWidth = pixelWidth + fm.charWidth(chars[i]);
if(pixelWidth >= (width - 10)) {
break;
}
}
String newString = WordUtils.wrap(string, i, "\n",false);
String[] splitString = newString.split("\n");
for(String str : splitString) {
newTextList.add(str);
textToFontMap.put(string, font);
}
} else {
newTextList.add(string);
textToFontMap.put(string, font);
}
}
}
Font font = new Font("Arial", Font.BOLD, 14);
int spaceOfLineHeight = (textToFontMap.size() - 1) * 7;
int spaceOfText = textToFontMap.size() * font.getSize();
int totalSpace = spaceOfLineHeight + spaceOfText ;
int marginRemaining = height - totalSpace;
int tempHt = marginRemaining / 2 + 10;
String txt = null;
for(Map.Entry<String, Font> entry : textToFontMap.entrySet()) {
txt = entry.getKey();
font = entry.getValue();
g2d.setFont(font);
fm = g2d.getFontMetrics();
int x = (width - fm.stringWidth(txt)) / 2;
int y = tempHt;
g2d.drawString(txt, x, y);
tempHt = tempHt + fm.getHeight();
}
// g2d.drawString(text.getIterator(), 0, (int)lm.getAscent() + lm.getHeight());
// g2d.dispose();
return img;
}
// Code with JTextPane ------------------------------------------
public static BufferedImage getTextImage(final Map < String, String > textToThemeMap, final Properties prop, final int height, final int width) throws Exception {
JFrame f = new JFrame();
f.setSize(width, height);
final StyleContext sc = new StyleContext();
DefaultStyledDocument doc = new DefaultStyledDocument(sc);
final JTextPane pane = new JTextPane(doc);
pane.setSize(width, height);
// Build the styles
final Paragraph[] content = new Paragraph[1];
Run[] runArray = new Run[textToThemeMap.size()];
int i = 0;
for (Map.Entry < String, String > entry: textToThemeMap.entrySet()) {
if (StringUtils.isNotBlank(entry.getValue().trim()) && StringUtils.isNotBlank(entry.getKey().trim())) {
Run run = new Run(entry.getValue().trim(), entry.getKey());
runArray[i++] = run;
}
}
content[0] = new Paragraph(null, runArray);
/*createDocumentStyles(sc, prop,textToThemeMap.values());
addText(pane, sc, sc.getStyle("default"), content);
pane.setEditable(false);*/
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
try {
createDocumentStyles(sc, prop, textToThemeMap.values());
} catch (MalformedURLException e) {
//e.printStackTrace();
}
addText(pane, sc, sc.getStyle("default"), content);
pane.setEditable(false);
}
});
} catch (Exception e) {
System.out.println("Exception when constructing document: " + e);
}
f.getContentPane().add(pane);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D gd = img.createGraphics();
f.paint(gd);
f.dispose();
/*ImageIO.write(img, "png", new File("C:\\Users\\spande0\\Desktop\\a.png"));
System.out.println("done");*/
return img;
}
I suspect the issue is in your 'Y' computation.
int spaceOfLineHeight = (newTextList.size() - 1) * 7;
int spaceOfText = newTextList.size() * font.getSize();
int totalSpace = spaceOfLineHeight + spaceOfText;
int marginRemaining = height - totalSpace;
int tempHt = marginRemaining / 2 + 10;
You have to keep the height occupied by the previous lines, and add it to the current 'Y'.
At the moment, for all the lines, the 'Y' values is same.
Declare prevHeight outside the for loop. and then do the following.
int tempHt = marginRemaining / 2 + 10;
tempHT += prevHeight;
prevHeight = tempHeight
Based on the comments, I will suggest you to break down your function into two smaller functions.
// Loop through the strings and find out how lines are split and calculate the X, Y
// This function will give the expected lines
splitLinesAndComputeResult
// Just render the lines
renderLines
Actually I need to extract font color of each character , found this below piece of code from a forum but while executing it throws me the error
Apr 19, 2013 6:23:45 PM org.apache.pdfbox.util.operator.pagedrawer.FillNonZeroRule process
WARNING: java.lang.ClassCastException: org.apache.pdfbox.util.PDFStreamEngine cannot be cast to org.apache.pdfbox.pdfviewer.PageDrawer
java.lang.ClassCastException: org.apache.pdfbox.util.PDFStreamEngine cannot be cast to org.apache.pdfbox.pdfviewer.PageDrawer"
PDDocument doc = null;
try {
doc = PDDocument.load("C:/Path/To/Pdf/Sample.pdf");
PDFStreamEngine engine = new PDFStreamEngine(ResourceLoader.loadProperties("org/apache/pdfbox/resources/PageDrawer.properties"));
PDPage page = (PDPage)doc.getDocumentCatalog().getAllPages().get(0);
engine.processStream(page, page.findResources(), page.getContents().getStream());
PDGraphicsState graphicState = engine.getGraphicsState();
System.out.println(graphicState.getStrokingColor().getColorSpace().getName());
float colorSpaceValues[] = graphicState.getStrokingColor().getColorSpaceValue();
for (float c : colorSpaceValues) {
System.out.println(c * 255);
}
}
finally {
if (doc != null) {
doc.close();
}
Can any one help me out
thanks
Have a look at org.apache.pdfbox.pdfviewer.PageDrawer which contains:
protected void processTextPosition( TextPosition text )
{
try
{
PDGraphicsState graphicsState = getGraphicsState();
Composite composite;
Paint paint;
switch(graphicsState.getTextState().getRenderingMode())
{
case PDTextState.RENDERING_MODE_FILL_TEXT:
composite = graphicsState.getNonStrokeJavaComposite();
paint = graphicsState.getNonStrokingColor().getJavaColor();
if (paint == null)
{
paint = graphicsState.getNonStrokingColor().getPaint(pageSize.height);
}
break;
case PDTextState.RENDERING_MODE_STROKE_TEXT:
composite = graphicsState.getStrokeJavaComposite();
paint = graphicsState.getStrokingColor().getJavaColor();
if (paint == null)
{
paint = graphicsState.getStrokingColor().getPaint(pageSize.height);
}
break;
case PDTextState.RENDERING_MODE_NEITHER_FILL_NOR_STROKE_TEXT:
//basic support for text rendering mode "invisible"
Color nsc = graphicsState.getStrokingColor().getJavaColor();
float[] components = {Color.black.getRed(),Color.black.getGreen(),Color.black.getBlue()};
paint = new Color(nsc.getColorSpace(),components,0f);
composite = graphicsState.getStrokeJavaComposite();
break;
default:
// TODO : need to implement....
LOG.debug("Unsupported RenderingMode "
+ this.getGraphicsState().getTextState().getRenderingMode()
+ " in PageDrawer.processTextPosition()."
+ " Using RenderingMode "
+ PDTextState.RENDERING_MODE_FILL_TEXT
+ " instead");
composite = graphicsState.getNonStrokeJavaComposite();
paint = graphicsState.getNonStrokingColor().getJavaColor();
}
graphics.setComposite(composite);
graphics.setPaint(paint);
PDFont font = text.getFont();
Matrix textPos = text.getTextPos().copy();
float x = textPos.getXPosition();
// the 0,0-reference has to be moved from the lower left (PDF) to the upper left (AWT-graphics)
float y = pageSize.height - textPos.getYPosition();
// Set translation to 0,0. We only need the scaling and shearing
textPos.setValue(2, 0, 0);
textPos.setValue(2, 1, 0);
// because of the moved 0,0-reference, we have to shear in the opposite direction
textPos.setValue(0, 1, (-1)*textPos.getValue(0, 1));
textPos.setValue(1, 0, (-1)*textPos.getValue(1, 0));
AffineTransform at = textPos.createAffineTransform();
PDMatrix fontMatrix = font.getFontMatrix();
at.scale(fontMatrix.getValue(0, 0) * 1000f, fontMatrix.getValue(1, 1) * 1000f);
//TODO setClip() is a massive performance hot spot. Investigate optimization possibilities
graphics.setClip(graphicsState.getCurrentClippingPath());
// the fontSize is no longer needed as it is already part of the transformation
// we should remove it from the parameter list in the long run
font.drawString( text.getCharacter(), text.getCodePoints(), graphics, 1, at, x, y );
}
catch( IOException io )
{
io.printStackTrace();
}
}
and which shows how to extract colours and other attributes.