Multiple connectors between Apache POI shapes - java

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:

Related

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);
}
}
}
}

Set appearance stream on highlight annotation with iText7

I have a PDF viewer that doesn't show highlights if they do not have an appearance stream. I'm trying out iText 7 core in java to try and add highlight annotations to PDFs but these annotations do not have appearance streams, and thus I'm looking to try and add them myself when writing the annotations to the PDF file.
I've come across this old answer, but it's for C# and iText 5, and I can't seem to figure out how to replicate it in iText 7 with a successful result.
So my question is thus: how do you set appearance streams on the highlighting annotations in iText 7 core that are working?
The furthest I've gotten with the code is shown below. I'm using the RegexBasedLocationExtrationStrategy class to find the locations of all search words in the pdf.
RegexBasedLocationExtractionStrategy evntlstnr = new RegexBasedLocationExtractionStrategy(pattern);
for (int pIdx = 0; pIdx < pdfDoc.getNumberOfPages(); ++pIdx) {
final PdfPage page = pdfDoc.getPage(pIdx + 1);
new PdfCanvasProcessor(evntlstnr).processPageContent(page);
Collection<IPdfTextLocation> locations = evntlstnr.getResultantLocations();
for (IPdfTextLocation location : locations) {
Rectangle rect = location.getRectangle();
// Specify quad points in Z-like order
// [0,1] x1,y1 [2,3] x2,y2
// [4,5] x3,y3 [6,7] x4,y4
float[] quads = new float[8];
quads[0] = rect.getX();
quads[1] = rect.getY() + rect.getHeight();
quads[2] = rect.getX() + rect.getWidth();
quads[3] = quads[1];
quads[4] = quads[0];
quads[5] = rect.getY();
quads[6] = quads[2];
quads[7] = quads[5];
Color highlightColor = new DeviceRgb(0f, 0f, 1f);
PdfTextMarkupAnnotation highlight = PdfTextMarkupAnnotation.createHighLight(rect, quads);
highlight.setColor(highlightColor);
Rectangle appearRect = new Rectangle(0f, 0f, rect.getWidth(), rect.getHeight());
PdfFormXObject appearObj = new PdfFormXObject(appearRect);
final PdfResources appearRes = appearObj.getResources();
PdfExtGState extGState = new PdfExtGState();
extGState.setBlendMode(PdfExtGState.BM_MULTIPLY);
appearRes.addExtGState(extGState);
appearObj.setBBox(new PdfArray(new float[] {0f, 0f, rect.getWidth(), rect.getHeight()}));
PdfShading appearShading = new PdfShading.Axial(highlightColor.getColorSpace(), 0f, 0f, highlightColor.getColorValue(), 1f, 1f, highlightColor.getColorValue());
appearRes.addShading(appearShading);
appearRes.addColorSpace(highlightColor.getColorSpace());
PdfAnnotationAppearance appearance = new PdfAnnotationAppearance(appearObj.getPdfObject());
highlight.setNormalAppearance(appearance);
highlight.setFlag(PdfAnnotation.PRINT);
page.addAnnotation(highlight);
}
}
Using Samuel's answer I stumbled my way to a working answer.
I'm no expect in the PDF standard and this framework (iText), but my hypothesis, based on my working example below, is that the rectangle I was trying to write for the highlight is a crude fall-back method for "faking" the highlight rectangle when the viewer cannot render the annotations (since they have no appearance stream). Realizing this that the two operations are not linked, I came to the working example shown below. Hope this helps others in the future.
RegexBasedLocationExtractionStrategy evntlstnr = new RegexBasedLocationExtractionStrategy(pattern);
for (int pIdx = 0; pIdx < pdfDoc.getNumberOfPages(); ++pIdx) {
final PdfPage page = pdfDoc.getPage(pIdx + 1);
new PdfCanvasProcessor(evntlstnr).processPageContent(page);
Collection<IPdfTextLocation> locations = evntlstnr.getResultantLocations();
for (IPdfTextLocation location : locations) {
Rectangle rect = location.getRectangle();
// Specify quad points in Z-like order
// [0,1] x1,y1 [2,3] x2,y2
// [4,5] x3,y3 [6,7] x4,y4
float[] quads = new float[8];
quads[0] = rect.getX();
quads[1] = rect.getY() + rect.getHeight();
quads[2] = rect.getX() + rect.getWidth();
quads[3] = quads[1];
quads[4] = quads[0];
quads[5] = rect.getY();
quads[6] = quads[2];
quads[7] = quads[5];
Color highlightColor = new DeviceRgb(1f, 1f, 0f);
PdfTextMarkupAnnotation highlight = PdfTextMarkupAnnotation.createHighLight(rect, quads);
highlight.setColor(highlightColor);
highlight.setFlag(PdfAnnotation.PRINT);
page.addAnnotation(highlight);
PdfCanvas canvas = new PdfCanvas(page);
PdfExtGState extGState = new PdfExtGState();
extGState.setBlendMode(PdfExtGState.BM_MULTIPLY);
canvas.setExtGState(extGState);
canvas.rectangle(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
canvas.setFillColor(highlightColor);
canvas.fill();
canvas.release();
}
}

detectMultiScale parameters in OpenCV 2.4.8 , 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; }

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.

Scaling an image with LibGDX SpriteBatches

I have my image (for the sake of explaining, lets call it Image.png) and I'm trying to get it to scale to properly fit in my Bodies I have drawn. The bodies and everything work with the debug but I'm not a fan of it.. I'm using a SpriteBatch to draw the background image onto the screen(it would be nice to scale that too). How would I scaleImage.png to the same size/position as a Dynamic body that has been rendered?
EDIT:
While drawing the images, I cant get them to match up with the debug render Bodies..
Creating Body:
BodyDef bodydef2 = new BodyDef();
bodydef2.type = BodyType.DynamicBody;
bodydef2.position.set(camera.viewportWidth + 30.0f, (int)(Math.random()*camera.viewportHeight)%(LastPlatformY+5)+20);
//System.out.println(bodydef2.position.y + " " + LastPlatformY);
Body block = world.createBody(bodydef2);
PolygonShape Shape2 = new PolygonShape();
Shape2.setAsBox(750*WORLD_TO_BOX, 200*WORLD_TO_BOX);
FixtureDef fixtureDef2 = new FixtureDef();
fixtureDef2.shape = Shape2;
fixtureDef2.density = 1000.0f;
fixtureDef2.friction = 0.0f;
fixtureDef2.restitution = 0;
block.setLinearVelocity(new Vector2((float) (Platform_Velocity*-1), 0));
block.createFixture(fixtureDef2);
//Lock 'block' to X-Axis, Relative to floor.
PrismaticJointDef jointDef = new PrismaticJointDef();
jointDef.collideConnected = true;
jointDef.initialize(block, groundBody, block.getWorldCenter(), new Vector2(1, 0));
world.createJoint(jointDef);
Platforms.add(block);
Platforms_Created++;
LastPlatformY = (int)bodydef2.position.y;
Drawing Image:
sp.draw(platforms, (float)(Platforms.get(i).getPosition().x), (float)(Platforms.get(i).getPosition().y), 75,20);
EDIT #2:
turns out that if your camera is smaller than the size of your screen you have to do some compensation to account for that variation in positions.. Problem solved, thanks!
Just save the size of your body in two variables while creating your body and then call the appropriate draw method.
To get the position of your object call body.getPosition().
For example
Texture t = assetManager.get("your texture", Texture.class);
BodyDef bodyDef = new BodyDef();
body.type = BodyType.DynamicBody
float width = 64 * WORLD_TO_BOX;
float height = 64 * WORLD_TO_BOX;
Shape shape = new PolygonShape();
float[] points = new float[]{0,0,width,0,width,height,0, height};
shape.set(points);
FixtureDef def = new FixtureDef();
def.shape = shape;
...
body.createFixture(def);
shape.dispose();
And later when you want to draw
public void render(Spritebatch batch) {
batch.draw(t, body.getPosition().x * BOX_TO_WORLD, body.getPosition().y * BOX_TO_WORLD, width * BOX_TO_WORLD, height * BOX_TO_WORLD);
}

Categories