detectMultiScale parameters in OpenCV 2.4.8 , Java - java

I'm trying to detect faces from a video stream using OpenCV 2.4.8 with Java using detectMultiScale. When searching through the web I noticed two versions of it with different parameter lists. Like here:
detectMultiScale(image, faceDetections) in [here][1] and face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) )
When I used it inside my code it gives an error :
OpenCV Error: Bad flag (parameter or structure field) (Unrecognized or unsupported array type) in cvGetMat
When I debug the code I see that error occurs at line:
face_cascade.detectMultiScale(frame_gray, faces);
I'm confused with these two parameter method because in OpenCV documentation site they have only one method with seven parameters.
detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())
Can anyone please describe what is this two parameter method and does it has any connection with the error in my code. Following is the code I was checking on:
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
public class FaceDetectSVM {
/**
* #param args
*/
public static void main(String[] args) {
//load opencv native library
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
CascadeClassifier face_cascade = new CascadeClassifier("haarcascade_frontalface_alt.xml");
CascadeClassifier eyes_cascade = new CascadeClassifier("haarcascade_eye.xml");
String window_name = "Capture - Face detection.jpg";
System.out.println("capture through camera "+Core.VERSION);
//load the face xml cascade
if(!face_cascade.load("haarcascade_frontalface_alt.xml"))
{
System.out.println("Error loading face cascade");
}
else
{
System.out.println("Success loading face cascade");
}
//load the eyes xml cascade
if(!eyes_cascade.load("haarcascade_eye.xml"))
{
System.out.println("Error loading eyes cascade");
}
else
{
System.out.println("Success loading eyes cascade");
}
//detect default camera
VideoCapture capture = new VideoCapture(0);
if(!capture.isOpened())
{
System.out.println("Did not connected to camera.");
}
else
{
System.out.println("Conected to camera: "+capture.toString());
}
//create new Mat image
Mat frame = new Mat();
while(true){
capture.retrieve(frame);
Mat frame_gray = new Mat();
Imgproc.cvtColor(frame, frame_gray, Imgproc.COLOR_BGRA2GRAY);
Imgproc.equalizeHist(frame_gray, frame_gray);
MatOfRect faces = new MatOfRect();
face_cascade.detectMultiScale(frame_gray, faces);
Rect[] facesArray = faces.toArray();
for(int i=0; i<facesArray.length; i++)
{
Point center = new Point(facesArray[i].x + facesArray[i].width * 0.5, facesArray[i].y + facesArray[i].height * 0.5);
Core.ellipse(frame, center, new Size(facesArray[i].width * 0.5, facesArray[i].height * 0.5), 0, 0, 360, new Scalar(255, 0, 255), 4, 8, 0);
Mat faceROI = frame_gray.submat(facesArray[i]);
MatOfRect eyes = new MatOfRect();
//-- In each face, detect eyes
eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0,new Size(30,30), new Size());
Rect[] eyesArray = eyes.toArray();
for (int j = 0; j < eyesArray.length; j++)
{
Point center1 = new Point(facesArray[i].x + eyesArray[i].x + eyesArray[i].width * 0.5, facesArray[i].y + eyesArray[i].y + eyesArray[i].height * 0.5);
int radius = (int) Math.round((eyesArray[i].width + eyesArray[i].height) * 0.25);
Core.circle(frame, center1, radius, new Scalar(255, 0, 0), 4, 8, 0);
}
}
Highgui.imwrite(window_name, frame);
capture.release();
}
}
}

OpenCV is written in C/C++. Java wrappers allows access to native code via JNI. Unlike C++, Java doesn't support default parameter values. That documentation is for C++ and so has one function with 5 default parameter values. To cover for that, OpenCV Java wrapper has 6 methods. The error you are getting, ideally shouldn't be because of this.
Try below.
capture.release() is called in loop. Release should happen outside while loop. Use like
while( !done ) { ... }
After capture.retrieve(frame);, add if( frame.empty() ) { continue; }

Related

Multiple connectors between Apache POI shapes

Recently i am working with Apache POI with Spring Boot and i am facing an issue. I want to represent database connections between entities, and i have a problem with visualizing multiple connections.
So the basic problem of mine is separating connections.
Here is my starting: 1
You can't see but there is multiple connections between this two rectangles, but because of the same start and end point, they are uncover each others.
The generated XML-code is the following:
<p:cxnSp>
<p:nvCxnSpPr>
<p:cNvPr name="Connector 7" id="7" />
<p:cNvCxnSpPr>
<a:stCxn id="2" idx="3" />
<a:endCxn id="3" idx="1" />
</p:cNvCxnSpPr>
<p:nvPr />
</p:nvCxnSpPr>
<p:spPr>
<a:xfrm flipV="1">
<a:off y="2199409" x="2616200" />
<a:ext cy="1318491" cx="2413000" />
</a:xfrm>
<a:prstGeom prst="curvedConnector3">
<a:avLst />
</a:prstGeom>
<a:ln w="9525">
<a:solidFill>
<a:srgbClr val="000000" />
</a:solidFill>
</a:ln>
</p:spPr>
</p:cxnSp>
So what i want to do is set the curved conectors midpoint in a different values, like in this image (i do this manually for the example):
2
I try to add some other GeomGuide element to the connector but the result is an unstable pptx file with this:
<a:prstGeom prst="curvedConnector3">
<a:avLst>
<a:gd name="adj1" fmla="val 57365" />
</a:avLst>
</a:prstGeom>
Relevant java code snippet for this:
XSLFConnectorShape connector1 = slide.createConnector();
CTNonVisualConnectorProperties cx = ctConnector.getNvCxnSpPr().getCNvCxnSpPr();
CTConnection start = cx.addNewStCxn();
start.setId(shapeIdStart);
start.setIdx(rel.getStartSide());
CTConnection end = cx.addNewEndCxn();
end.setId(shapeIdEnd);
end.setIdx(rel.getEndSide());
CTGeomGuideList ctGeomGuideList = ctConnector.getSpPr().getPrstGeom().getAvLst();
CTGeomGuide ctGeomGuide = ctGeomGuideList.addNewGd();
ctGeomGuide.setName("adj");
ctGeomGuide.setFmla("val 45000");
Your provided code snippet is not complete. So it is not clear whether this is the one and only problem. But ctGeomGuide.setName("adj"); is wrong in any case. The adjust handles are numbered and there is no adjust handle called adj only. It would must be ctGeomGuide.setName("adj1");.
Folowing code is a Minimal, Reproducible Example which works and creates your wanted result.
import java.io.FileOutputStream;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.sl.usermodel.*;
import org.openxmlformats.schemas.presentationml.x2006.main.*;
import org.openxmlformats.schemas.drawingml.x2006.main.*;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.Color;
public class CreatePPTXConnectorShapes {
private static XSLFConnectorShape createConnector(XSLFSlide slide, XSLFAutoShape shape1, XSLFAutoShape shape2) {
XSLFConnectorShape connector = slide.createConnector();
connector.setShapeType(ShapeType.CURVED_CONNECTOR_3);
connector.setAnchor(new Rectangle2D.Double( //connector is diagonal in a rectangle
shape1.getAnchor().getMaxX(), // top left x of that rectangle is x position of right edge of shape1
shape2.getAnchor().getCenterY(), // top left y of that rectangle is center y of shape2 as shape2 is above shape1
shape2.getAnchor().getX()-shape1.getAnchor().getMaxX(), // width of that rectanle is x of shape2 minus x position of right edge of shape1 as shape2 is right of shape1
shape1.getAnchor().getCenterY()-shape2.getAnchor().getCenterY() // height of that rectanle is center y of shape1 minus center y of shape2 as shape2 is above shape1
));
connector.setFlipVertical(true); // the rectangle needs to be flipped vertically as the connector shall be diagonal from bottom left to top right
CTConnector ctConnector = (CTConnector)connector.getXmlObject();
CTNonVisualConnectorProperties cx = ctConnector.getNvCxnSpPr().getCNvCxnSpPr();
CTConnection start = cx.addNewStCxn();
start.setId(shape1.getShapeId());
start.setIdx(3); // connecting point 3 is center of right edge
CTConnection end = cx.addNewEndCxn();
end.setId(shape2.getShapeId());
end.setIdx(1); // connecting point 1 is center of left edge
return connector;
}
public static void main(String[] args) throws Exception {
XMLSlideShow slideShow = new XMLSlideShow();
XSLFSlide slide = slideShow.createSlide();
XSLFAutoShape shape1 = slide.createAutoShape();
shape1.setShapeType(ShapeType.RECT);
shape1.setFillColor(Color.GREEN);
shape1.setAnchor(new Rectangle(50, 150, 150, 100));
XSLFAutoShape shape2 = slide.createAutoShape();
shape2.setShapeType(ShapeType.RECT);
shape2.setFillColor(Color.GREEN);
shape2.setAnchor(new Rectangle(500, 50, 150, 100));
// first connector
XSLFConnectorShape connector1 = createConnector(slide, shape1, shape2);
CTConnector ctConnector = (CTConnector)connector1.getXmlObject();
CTGeomGuideList ctGeomGuideList = ctConnector.getSpPr().getPrstGeom().getAvLst();
CTGeomGuide ctGeomGuide = ctGeomGuideList.addNewGd();
ctGeomGuide.setName("adj1");
ctGeomGuide.setFmla("val 45000");
//second connector
XSLFConnectorShape connector2 = createConnector(slide, shape1, shape2);
ctConnector = (CTConnector)connector2.getXmlObject();
ctGeomGuideList = ctConnector.getSpPr().getPrstGeom().getAvLst();
ctGeomGuide = ctGeomGuideList.addNewGd();
ctGeomGuide.setName("adj1");
ctGeomGuide.setFmla("val 57365");
FileOutputStream out = new FileOutputStream("CreatePPTXConnectorShapes.pptx");
slideShow.write(out);
out.close();
}
}
Result:

Show SUM Value above Stacked bar with Apache poi

I'm currently working on functionality, that is supposed to generate stacked chart inside .pptx file.
For this I'm using code from here:
java create a chart in a powerpoint using APACHE POI
I did some modifications. Mainly I set grouping to Stacked and overlap to 100 (so the subBars looks like one bigger bar).
Now I need to display SUM of subBars values above each Bar. Aaaaand here comes my question. How can I achieve this (second pohoto below) using Apache Poi and openxmlformats.schemas.drawingml.x2006.chart?
One idea was to create another SubBar on top, make it transparent and set it's label to my desired SUM, but I cannot find a way, to set label (only Value and in this case, my transparent SubBar takes too much space and it just looks terrible - as in the photo below).
This is what I need it to look like:
I cannot find any documentation or anything apart from some threads here on StackOverflow.
Do you guys have some idea, on how to achieve this?
EDIT 1
With help from Alex I was able to print SUM values above BARs. Now I just need to get rid of these 0 values:
EDIT 2
There was a problem mentioned by Axel, that caused zeroes to be displayed (from EDIT 1). Axel edited the code in his answer, so now zeroes are gone.
How would you do that using PowerPoint? The only way I see is using a combination of stacked bar chart with line chart where the line chart displays the sum values and is set invisible. So only the data labels of the line chart are visible. The way as described in How to add total labels to stacked column chart in Excel?.
Using current apache poi 4.1.2 this can be achieved using the new XDDF stuff. For a Excel chart, I have shown that in How to generate editable Stacked-bar-chart using apache poi 4.0.1 and java?.
I will show a complete example for a PowerPoint chart as well:
import java.io.*;
import org.apache.poi.xslf.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
import java.util.*;
public class CreatePowerPointStackedBarChartXDDFChart {
public static void main(String[] args) throws Exception {
try (XMLSlideShow slideShow = new XMLSlideShow()) {
XSLFSlide slide = slideShow.createSlide();
// create the data
String[] categories = new String[]{"KW1", "KW2", "KW3", "KW4", "KW5", "KW6"};
int numOfPoints = categories.length;
Double[][] values = new Double [][] {
new Double[]{10d, 0d, 20d, 5d, 30d, 10d},
new Double[]{15d, 35d, 25d, 15d, 10d, 8d},
new Double[]{5d, 15d, 0d, 25d, 15d, 0d},
new Double[]{10d, 5d, 30d, 30d, 20d, 12d}
};
Double[] sums = new Double[numOfPoints];
for (int i = 0; i < sums.length; i++) {
double sum = 0;
for (Double[] valueRow : values) {
sum += valueRow[i];
}
sums[i] = sum;
}
// create the chart
XSLFChart chart = slideShow.createChart();
// add chart to slide
slide.addChart(chart, new java.awt.geom.Rectangle2D.Double(1d*Units.EMU_PER_CENTIMETER, 1d*Units.EMU_PER_CENTIMETER, 20d*Units.EMU_PER_CENTIMETER, 15d*Units.EMU_PER_CENTIMETER));
// bar chart
// create data sources
String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 0);
List<XDDFNumericalDataSource<Double>> valuesData = new ArrayList<XDDFNumericalDataSource<Double>>();
int c = 1;
for (Double[] valueRow : values) {
String valuesDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, c, c));
valuesData.add(XDDFDataSourcesFactory.fromArray(valueRow, valuesDataRange, c));
c++;
}
// create axis
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
// Set AxisCrossBetween, so the left axis crosses the category axis between the categories.
// Else first and last category is exactly on cross points and the bars are only half visible.
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// create chart data
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
((XDDFBarChartData)data).setBarDirection(BarDirection.COL);
// stacked bar chart
((XDDFBarChartData)data).setBarGrouping(BarGrouping.STACKED);
((XDDFBarChartData)data).setOverlap((byte)100);
// create series
if (valuesData.size() == 1) {
// if only one series do not vary colors for each bar
((XDDFBarChartData)data).setVaryColors(false);
} else {
// if more than one series do vary colors of the series
((XDDFBarChartData)data).setVaryColors(true);
}
for (int s = 0; s < valuesData.size(); s++) {
XDDFChartData.Series series = data.addSeries(categoriesData, valuesData.get(s));
series.setTitle("Series"+(s+1), chart.setSheetTitle("Series"+(s+1), s+1));
}
// plot chart data
chart.plot(data);
// add data labels
for (int s = 0 ; s < valuesData.size(); s++) {
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).addNewDLbls();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls()
.addNewDLblPos().setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STDLblPos.CTR);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewNumFmt();
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getNumFmt()
.setSourceLinked(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().getNumFmt()
.setFormatCode("0;-0;");
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowVal().setVal(true);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowLegendKey().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowCatName().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowSerName().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowPercent().setVal(false);
chart.getCTChart().getPlotArea().getBarChartArray(0).getSerArray(s).getDLbls().addNewShowBubbleSize().setVal(false);
}
// line chart
c = values.length + 1;
// create data source
String sumDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, c, c));
XDDFNumericalDataSource<Double> sumData = XDDFDataSourcesFactory.fromArray(sums, sumDataRange, c);
// axis must be there but must not be visible
bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setVisible(false);
leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setVisible(false);
// set correct cross axis
bottomAxis.crossAxis(leftAxis);
leftAxis.crossAxis(bottomAxis);
data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
XDDFChartData.Series series = data.addSeries(categoriesData, sumData);
series.setTitle("sum", chart.setSheetTitle("sum", c));
((XDDFLineChartData.Series)series).setSmooth(false);
((XDDFLineChartData.Series)series).setMarkerStyle(MarkerStyle.NONE);
// don't show the line
XDDFShapeProperties shapeProperties = new XDDFShapeProperties();
shapeProperties.setLineProperties(new XDDFLineProperties(new XDDFNoFillProperties()));
series.setShapeProperties(shapeProperties);
// plot chart data
chart.plot(data);
// correct the id and order, must not start 0 again because there are bar series already
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getIdx().setVal(c);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getOrder().setVal(c);
// add data labels
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).addNewDLbls();
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls()
.addNewDLblPos().setVal(org.openxmlformats.schemas.drawingml.x2006.chart.STDLblPos.T);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewNumFmt();
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().getNumFmt()
.setSourceLinked(false);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().getNumFmt()
.setFormatCode("0;-0;");
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowVal().setVal(true);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowLegendKey().setVal(false);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowCatName().setVal(false);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowSerName().setVal(false);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowPercent().setVal(false);
chart.getCTChart().getPlotArea().getLineChartArray(0).getSerArray(0).getDLbls().addNewShowBubbleSize().setVal(false);
// Write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("CreatePowerPointStackedBarChartXDDFChart.pptx")) {
slideShow.write(fileOut);
}
}
}
}

How can I optimize the weight of SVG images generated using Apache Batik?

I have written the following code using Apache Batik in order to generate SVG images (full source available on GitHub) representing badges showing if code passes a SonarQube quality gate or not:
private SVGGraphics2D generateFor(final QualityGateStatus status) {
// new SVG graphics
final SVGGraphics2D svgGraphics2D = new SVGGraphics2D(this.svgGeneratorContext, false);
// set SVG canvas size
svgGraphics2D.setSVGCanvasSize(new Dimension(LABEL_WIDTH + status.displayWidth(), CANVAS_HEIGHT));
// set font
svgGraphics2D.setFont(FONT_FAMILY);
// draw Label background
svgGraphics2D.setColor(COLOR_BACKGROUND_LABEL);
svgGraphics2D.fillRoundRect(0, 0, LABEL_WIDTH, CANVAS_HEIGHT, BACKGROUND_CORNER_ARC_DIAMETER, BACKGROUND_CORNER_ARC_DIAMETER);
svgGraphics2D.fillRect(LABEL_WIDTH - BACKGROUND_CORNER_ARC_DIAMETER, 0, BACKGROUND_CORNER_ARC_DIAMETER, CANVAS_HEIGHT);
// draw Label text shadow
svgGraphics2D.setColor(COLOR_SHADOW);
svgGraphics2D.drawString(LABEL_TEXT, X_MARGIN, Y_OFFSET_SHADOW);
// draw Label text
svgGraphics2D.setColor(COLOR_TEXT);
svgGraphics2D.drawString(LABEL_TEXT, X_MARGIN, Y_OFFSET_TEXT);
// draw result background
svgGraphics2D.setColor(status.displayBackgroundColor());
svgGraphics2D.fillRoundRect(LABEL_WIDTH, 0, status.displayWidth(), CANVAS_HEIGHT, BACKGROUND_CORNER_ARC_DIAMETER, BACKGROUND_CORNER_ARC_DIAMETER);
svgGraphics2D.fillRect(LABEL_WIDTH, 0, BACKGROUND_CORNER_ARC_DIAMETER, CANVAS_HEIGHT);
// draw result text shadow
svgGraphics2D.setColor(COLOR_SHADOW);
svgGraphics2D.drawString(status.displayText(), LABEL_WIDTH + X_MARGIN, 15);
// draw result text
svgGraphics2D.setColor(COLOR_TEXT);
svgGraphics2D.drawString(status.displayText(), LABEL_WIDTH + X_MARGIN, 14);
return svgGraphics2D;
}
Examples of produced images (depending on parameters passed to the generateFor() method) can be seen on GitHub as well.
This code works fine, however currently the weight of a generated image is more or less 2KB, which is almost 3 times heavier than travis-ci badges that weight more or less 700 Bytes. Therefor I have the feeling that generated images could be simplified, sized down to ~1KB.
How can I achieve this using Apache Batik ? Should I use another library or use another approach ?
Thanks in advance for your insight and recommendations !
I tried generating your SVG using JFreeSVG 3.0, and with the GZIP option it creates files around 570 bytes. In plain text the SVG is around 1.7 kbytes.
Here is the test program I ran (based on your code, you'll also need your QualityGateStatus class to run this):
/*
* qualinsight-plugins-sonarqube-status
* Copyright (c) 2015, QualInsight
* http://www.qualinsight.com/
*
* This program is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program. If not, you can retrieve a copy
* from <http://www.gnu.org/licenses/>.
*/
import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.io.IOException;
import org.jfree.graphics2d.svg.SVGGraphics2D;
import org.jfree.graphics2d.svg.SVGUtils;
public final class SVGImageGenerator {
private static final int FONT_SIZE = 11;
private static final Font FONT_FAMILY = new Font("Verdana", Font.PLAIN, FONT_SIZE);
private static final int X_MARGIN = 4;
private static final int CANVAS_HEIGHT = 20;
private static final int LABEL_WIDTH = 46;
private static final String LABEL_TEXT = "quality";
private static final int BACKGROUND_CORNER_ARC_DIAMETER = 6;
private static final Color COLOR_BACKGROUND_LABEL = new Color(85, 85, 85, 255);
private static final Color COLOR_SHADOW = new Color(0, 0, 0, 85);
private static final Color COLOR_TEXT = new Color(255, 255, 255, 255);
private static final int Y_OFFSET_SHADOW = 14;
private static final int Y_OFFSET_TEXT = 14;
private static String generateFor(final QualityGateStatus status) {
// new SVG graphics
final SVGGraphics2D svgGraphics2D = new SVGGraphics2D(LABEL_WIDTH + status.displayWidth(), CANVAS_HEIGHT);
// set font
svgGraphics2D.setFont(FONT_FAMILY);
// draw Label background
svgGraphics2D.setColor(COLOR_BACKGROUND_LABEL);
svgGraphics2D.fillRoundRect(0, 0, LABEL_WIDTH, CANVAS_HEIGHT, BACKGROUND_CORNER_ARC_DIAMETER, BACKGROUND_CORNER_ARC_DIAMETER);
svgGraphics2D.fillRect(LABEL_WIDTH - BACKGROUND_CORNER_ARC_DIAMETER, 0, BACKGROUND_CORNER_ARC_DIAMETER, CANVAS_HEIGHT);
// draw Label text shadow
svgGraphics2D.setColor(COLOR_SHADOW);
svgGraphics2D.drawString(LABEL_TEXT, X_MARGIN, Y_OFFSET_SHADOW);
// draw Label text
svgGraphics2D.setColor(COLOR_TEXT);
svgGraphics2D.drawString(LABEL_TEXT, X_MARGIN, Y_OFFSET_TEXT);
// draw result background
svgGraphics2D.setColor(status.displayBackgroundColor());
svgGraphics2D.fillRoundRect(LABEL_WIDTH, 0, status.displayWidth(), CANVAS_HEIGHT, BACKGROUND_CORNER_ARC_DIAMETER, BACKGROUND_CORNER_ARC_DIAMETER);
svgGraphics2D.fillRect(LABEL_WIDTH, 0, BACKGROUND_CORNER_ARC_DIAMETER, CANVAS_HEIGHT);
// draw result text shadow
svgGraphics2D.setColor(COLOR_SHADOW);
svgGraphics2D.drawString(status.displayText(), LABEL_WIDTH + X_MARGIN, 15);
// draw result text
svgGraphics2D.setColor(COLOR_TEXT);
svgGraphics2D.drawString(status.displayText(), LABEL_WIDTH + X_MARGIN, 14);
return svgGraphics2D.getSVGElement();
}
public static void main(String[] args) {
try {
SVGUtils.writeToSVG(new File("error.svgz"), generateFor(QualityGateStatus.ERROR), true);
SVGUtils.writeToSVG(new File("none.svgz"), generateFor(QualityGateStatus.NONE), true);
SVGUtils.writeToSVG(new File("ok.svgz"), generateFor(QualityGateStatus.OK), true);
SVGUtils.writeToSVG(new File("server_error.svgz"), generateFor(QualityGateStatus.SERVER_ERROR), true);
SVGUtils.writeToSVG(new File("warn.svgz"), generateFor(QualityGateStatus.WARN), true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}

Java use a method multiple times but with changed parameters

I have a method reads coordinates from a file and uses them to render a GameObject at the specified coordinates writen on the file, this code looks like this:
public void ProcessText()
{
String file_name = "C:/Users/Server/Desktop/textText.txt";
try
{
ProcessCoords file = new ProcessCoords(file_name);
String[] aryLines = file.OpenFile();
int i;
for (i = 0; i < aryLines.length; i++)
{
System.out.println(aryLines[i]);
if(aryLines[i].startsWith("makeGrass:")) {
String Arguments = aryLines[i].substring(aryLines[i].indexOf(":")+1, aryLines[i].length());
String[] ArgArray = Arguments.substring(1, Arguments.length() - 2).split(" ");
this.makeGrass(Double.parseDouble(ArgArray[0]),
Double.parseDouble(ArgArray[1]),
Double.parseDouble(ArgArray[2]));
}
}
} catch(IOException e) {
System.out.println(e.getMessage());
}
}
and my text file would only have one line:
makeGrass:(x y z) // for example makeGrass:(1.22334 0.0 9.66678)
this all works fine now.. but there's no point in making this for only one single object. What I want to be able to do is have as many objects as I want from multiple coordinates, so my text file might look like this:
makeGrass:(0.0 1.0 5.0)
makeGrass:(8.0 1.0 2.0)
makeGrass:(4.0 1.0 7.0)
makeGrass:(0.0 1.0 2.0)
makeGrass:(2.0 1.0 7.0)
makeGrass:(5.0 1.0 6.0)
at the moment I use the code this.makeGrass only once and like that my grass model is only placed at those coordinates of the first line (the other lines cause a graphical glitch where they are just being put ontop of each other)
My question here is how I have to write the code so it gives me this.makeGrass multiple times: I want to render the grass model at the respective makeGrass coordinates as many times as there are makeGrass coordinates provided in the text file, how can I do that?
Thanks for any help!
edit: I was asked for more information.. here it is:
public class Vegetation extends GameComponent
{
private Game game;
GameObject grassLeaf1 = new GameObject();
Mesh grassLeaf1mesh = new Mesh("grassLeaf1.obj");
Material grassLeaf1material = new Material
(new Texture("GrassUVTex.png"), 1, 8, new Texture("GrassUVTex_NRM.jpg"), new Texture("GrassUVTex_DISP.jpg"), 0.008f, -0.5f);
MeshRenderer grassLeaf1Renderer = new MeshRenderer(grassLeaf1mesh, grassLeaf1material);
public Vegetation(Game game)
{
this.game = game;
}
public void makeGrass(double posX, double posY, double posZ)
{
grassLeaf1.AddComponent(grassLeaf1Renderer);
grassLeaf1.GetTransform().GetPos().Set((float)posX, (float)posY, (float)posZ);
grassLeaf1.GetTransform().SetScale(new Vector3f (2, 2, 2));
grassLeaf1.GetTransform().SetRot(new Quaternion(new Vector3f(0, 1, 0), (float) Math.toRadians(0)));
game.AddObject(grassLeaf1);
}
public void ProcessText()
{
grassLeaf1.AddComponent(new SaveGrass());
grassLeaf1.AddComponent(new ObjectManipulator(4.0f));
String file_name = "C:/Users/Server/Desktop/textText.txt";
try
{
ProcessCoords file = new ProcessCoords(file_name);
String[] aryLines = file.OpenFile();
int i;
for (i = 0; i < aryLines.length; i++)
{
System.out.println(aryLines[i]);
if(aryLines[i].startsWith("makeGrass:")) {
String Arguments = aryLines[i].substring(aryLines[i].indexOf(":")+1, aryLines[i].length());
String[] ArgArray = Arguments.substring(1, Arguments.length() - 2).split(" ");
this.makeGrass(Double.parseDouble(ArgArray[0]),
Double.parseDouble(ArgArray[1]),
Double.parseDouble(ArgArray[2]));
}
}
} catch(IOException e) {
System.out.println(e.getMessage());
}
}
}
The Vegetation Class handles creating a grass model and reading the coordinates of it from a text file. This here is said text file:
makeGrass:(0.6 1.0 2.8)
makeGrass:(5.6 1.0 9.8)
makeGrass:(2.6 1.0 4.8)
makeGrass:(7.6 1.0 3.8)
makeGrass:(0.6 1.0 2.8)
makeGrass:(0.6 1.0 4.8)
makeGrass:(2.6 1.0 2.8)
makeGrass:(0.6 1.0 0.8)
Now this should enable me to render 8 grass models at different positions but when I hit run all I can see is this:
http://www.pic-upload.de/view-27752444/Untitled.png.html
the grass is also super shiny because all other grass models are being placed also at this location.. something went wrong..
Okay I've found the mistake my make grass function was messed up, it needs to be like this:
public void makeGrass(double posX, double posY, double posZ)
{
GameObject grassLeaf1 = new GameObject();
Mesh grassLeaf1mesh = new Mesh("grassLeaf1.obj");
Material grassLeaf1material = new Material
(new Texture("GrassUVTex.png"), 1, 8, new Texture("GrassUVTex_NRM.jpg"), new Texture("GrassUVTex_DISP.jpg"), 0.008f, -0.5f);
MeshRenderer grassLeaf1Renderer = new MeshRenderer(grassLeaf1mesh, grassLeaf1material);
grassLeaf1.AddComponent(grassLeaf1Renderer);
grassLeaf1.GetTransform().GetPos().Set((float)posX, (float)posY, (float)posZ);
grassLeaf1.GetTransform().SetScale(new Vector3f (2, 2, 2));
grassLeaf1.GetTransform().SetRot(new Quaternion(new Vector3f(0, 1, 0), (float) Math.toRadians(0)));
game.AddObject(grassLeaf1);
}
only strange that once I've added the code into the makeGrass method I lost my input methods.. strange but not that of a problem for now..
I'm getting almost exactly what I wanted now.. here's the final result and the basis of my world editor. Thank you all very much, you've really helped me!
Here's my ShowOff picture: http://www.pic-upload.de/view-27752521/ShowOff.png.html
I'm sure I'll be back for more soon enough but at the moment I know everything and can extend this world editor on my own, thanks a lot to all who have helped me so far, hopefully I can return the favour some time!

Use of texture in extrude geometry (GWT)

I'm creating shapes with extrude geometry on GWT, now I want to apply textures on it but I am not able to apply it directly. How can I do that?
My code looks like :
ExtrudeGeometry extrudeMaterialBoard = null;
shapeExtrude.getExtrudeSettings().amount = (int) getMaterialThickness();
shapeExtrude.getExtrudeSettings().curveSegments = 1;
shapeExtrude.getExtrudeSettings().bevelThickness= 5;
shapeExtrude.getExtrudeSettings().bevelSize= 5;
shapeExtrude.getExtrudeSettings().bevelEnabled= true;
shapeExtrude.getExtrudeSettings().material = 0;
shapeExtrude.getExtrudeSettings().extrudeMaterial = 1;
extrudeMaterialBoard = new ExtrudeGeometry(DrawShape.getBottomBoard(), shapeExtrude.getExtrudeSettings());
camera = new PerspectiveCamera(
70, // fov
getRenderer().getAbsoluteAspectRation(), // aspect
1, // near
1000 // far
);
camera.getPosition().setZ(400);
String texture1 = "uvgrid0.jpg";
MeshBasicMaterial material = new MeshBasicMaterial();
material.setColor(getColor(COLOR_TRANSPARENT));
Texture texture = new Texture(texture1);
material.setMap(texture);
mesh = new Mesh(extrudeMaterialBoard, material);
getScene().add(mesh);
getRenderer().render(getScene(), camera);
If I use cube geometry then its running properly. But in case of extrude geometry its not working.
Thanks in advance.

Categories