I would love some help with this. I developed this program for class that reads in four .obj files and one file for a texture. It works fine in my IDE (Eclipse) but when i export it and use JavaSplice to create the final executable jar, it launches, shows a display window for a fraction of a second, then just crashes. With some testing and careful commenting, I've determined that it is not on the splicing end but rather my code. With commenting, I've determined that the problem lies in the Display Lists that read in the four .obj:
int objectOneDisplayList = glGenLists(1);
glNewList(objectOneDisplayList, GL_COMPILE);
{
Model m = null;
try
{
m = OBJLoader.loadModel(new File("res/circle.obj"));
}
catch(FileNotFoundException e)
{
e.printStackTrace();
Display.destroy();
}
catch(IOException e)
{
e.printStackTrace();
Display.destroy();
}
glBegin(GL_TRIANGLES);
for(Face face : m.faces)
{
glColor3f(0.0f, 0.75f, 0.0f);
Vector3f n1 = m.normals.get((int) face.normal.x - 1);
glNormal3f(n1.x, n1.y, n1.z);
Vector3f v1 = m.vertices.get((int) face.vertex.x - 1);
glVertex3f(v1.x, v1.y, v1.z);
Vector3f n2 = m.normals.get((int) face.normal.y - 1);
glNormal3f(n2.x, n2.y, n2.z);
Vector3f v2 = m.vertices.get((int) face.vertex.y - 1);
glVertex3f(v2.x, v2.y, v2.z);
Vector3f n3 = m.normals.get((int) face.normal.z - 1);
glNormal3f(n3.x, n3.y, n3.z);
Vector3f v3 = m.vertices.get((int) face.vertex.z - 1);
glVertex3f(v3.x, v3.y, v3.z);
}
glEnd();
}
glEndList();
There are four of those just with different filenames and list names. Now here is my OBJLoader Class:
package base;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.lwjgl.util.vector.Vector3f;
public class OBJLoader
{
public static Model loadModel(File f) throws FileNotFoundException, IOException
{
BufferedReader reader = new BufferedReader(new FileReader(f));
Model m = new Model();
String line;
while((line = reader.readLine()) != null)
{
if(line.startsWith("v "))
{
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.vertices.add(new Vector3f(x, y, z));
}
else if(line.startsWith("vn "))
{
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.normals.add(new Vector3f(x, y, z));
}
else if(line.startsWith("f "))
{
Vector3f vertexIndices = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[0]),
Float.valueOf(line.split(" ")[2].split("/")[0]),
Float.valueOf(line.split(" ")[3].split("/")[0]));
Vector3f normalIndices = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[2]),
Float.valueOf(line.split(" ")[2].split("/")[2]),
Float.valueOf(line.split(" ")[3].split("/")[2]));
m.faces.add(new Face(vertexIndices, normalIndices));
}
}
reader.close();
return m;
}
}
I think it is because I need to use InputFileStream. Could someone show me how I would rewrite this using that?
EDIT: Rewrote the OBJLoader to not use FileReader, still didn't work. I think I can't use any sort of Reader. How can I read the lines then?:
public class OBJLoader
{
public static Model loadModel(File f) throws FileNotFoundException, IOException
{
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
Model m = new Model();
String line;
while((line = reader.readLine()) != null)
{
if(line.startsWith("v "))
{
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.vertices.add(new Vector3f(x, y, z));
}
else if(line.startsWith("vn "))
{
float x = Float.valueOf(line.split(" ")[1]);
float y = Float.valueOf(line.split(" ")[2]);
float z = Float.valueOf(line.split(" ")[3]);
m.normals.add(new Vector3f(x, y, z));
}
else if(line.startsWith("f "))
{
Vector3f vertexIndices = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[0]),
Float.valueOf(line.split(" ")[2].split("/")[0]),
Float.valueOf(line.split(" ")[3].split("/")[0]));
Vector3f normalIndices = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[2]),
Float.valueOf(line.split(" ")[2].split("/")[2]),
Float.valueOf(line.split(" ")[3].split("/")[2]));
m.faces.add(new Face(vertexIndices, normalIndices));
}
}
reader.close();
return m;
}
}
Open command prompt, type:
java -jar "pathToYourJar.jar"
With this you can see what Exception the code throws.
About the crash, i think the problem can be resolved using InputStreams instead of Files.
Change:
BufferedReader reader = new BufferedReader(new InputStreamReader
(new FileInputStream(f)));
into
String path = "/package1/package2/file.obj";
InputStream source = ClassLoader.class.getResourceAsStream(path);
BufferedReader reader = new BufferedReader(new InputStreamReader
(source);
This will work both in Eclipse and with JARs.
Related
Say, I have an array of float points (function xy). The first image is trying with SkiaSharp, the second is with System.Drawing of .NET Framework.
I understand that I should use a method like CubicTo, but I don't see how to combine it to achieve the expected result.
The example was created in WindowsForms (only uses 2 PictureBox) and SkiaSharp nuget. It is similar with Xamarin, the question is the same.
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using SkiaSharp;
namespace SKLab
{
public partial class BasicTestForm : Form
{
float startX = -4, stopX = 4;
float yi = -4, ye = 4;
float w = 200, h = 150;
float stepX = 1;
float x, px;
float y, py;
// pixel to cartesian
float pixelFromX(float cartX) => w * (cartX - startX) / (stopX - startX);
// cartesian to pixel
float pixelFromY(float cartY) => h * (cartY - yi) / (ye - yi);
public BasicTestForm()
{
InitializeComponent();
SkiaPlot(pictureBox1);
DrawingPlot(pictureBox2);
}
private void SkiaPlot(PictureBox p)
{
p.Size = new Size((int)w, (int)h);
using (var surface = SKSurface.Create(new SKImageInfo(p.Width, p.Height))) {
SKCanvas g = surface.Canvas;
g.Clear(SKColors.White);
using (var paint = new SKPaint()) {
paint.Style = SKPaintStyle.Stroke;
paint.IsAntialias = true;
paint.Color = SKColors.CornflowerBlue;
paint.StrokeWidth = 2;
var path = new SKPath();
for (x = startX; x <= stopX; x += stepX) {
px = pixelFromX(x);
py = pixelFromY((float)Math.Sin(x));
if (x == startX) {
path.MoveTo(px, py);
} else {
path.LineTo(px, py);
}
}
g.DrawPath(path, paint);
}
using (SKImage image = surface.Snapshot())
using (SKData data = image.Encode(SKEncodedImageFormat.Png, 100))
using (MemoryStream mStream = new MemoryStream(data.ToArray())) {
p.Image = new Bitmap(mStream, false);
}
}
}
void DrawingPlot(PictureBox p)
{
p.Size = new Size((int)w, (int)h); ;
// Make the Bitmap.
var canvas = new Bitmap(p.ClientSize.Width, p.ClientSize.Height);
using (var g = Graphics.FromImage(canvas)) {
// Clear.
g.Clear(Color.White);
// curve
var points = new List<PointF>();
for (x = startX; x <= stopX; x += stepX) {
points.Add(new PointF
{
X = pixelFromX(x),
Y = pixelFromY((float)Math.Sin(x))
});
}
g.SmoothingMode = SmoothingMode.AntiAlias;
using (var pen = new Pen(Color.CornflowerBlue, 2)) {
g.DrawCurve(pen, points.ToArray());
}
}
// Display the result.
p.Image = canvas;
}
}
}
i am working in the preview of a fingerprint scaner using id3Fingerprint sdk and OpenCV. If i just show the preview from the id3fingerprint sdk all is fine, but if i load it to a Mat object of OpenCV in order to draw some rectangles in the image then:
1.- The fingerprints are displayed in right form but the rectangles are displayed as lines or pixels in random x,y location.
2.- The rectangles are displayed in right form but the fingerprints are displayed "blured" (look the image attached).fingerprints are blured
I think, my problem is when i convert the raw grayscale image (a byte array from the id3fingerprint sdk) to a RGB or RGBA image.
private void showPreview2(FingerImage image){
int height = 750;
int width = 750;
int currentWidth = 0;
int currentHeight = 0;
try {
currentWidth = image.getWidth();
currentHeight = image.getHeight();
} catch (FingerException ex) {
Logger.getLogger(CallingID3Example.class.getName()).log(Level.SEVERE, null, ex);
}
byte[] pixels = image.getPixels();
Mat dest = new Mat();
Mat source = new Mat();
Mat source2 = null;
source2 = new Mat(currentWidth, currentHeight, CvType.CV_8UC1);
source2.put(0, 0, pixels);
MatOfByte pix = new MatOfByte();
Imgcodecs.imencode(".bmp", source2, pix);
source2.put(0, 0, pix.toArray());
Imgproc.cvtColor(source2, source, Imgproc.COLOR_GRAY2RGBA);
try {
int i=0;
for(FingerImage finger : image.getSegments()){
Scalar color;
color = new Scalar(0, 250,0);
FingerBounds bound = image.getSegmentBounds()[i];
Imgproc.rectangle(source, new Point(bound.topLeft.x, bound.topLeft.y), new Point(bound.bottomRight.x, bound.bottomRight.y), color, 3);
double[] pixelTest;
pixelTest = source.get(bound.topLeft.x, bound.topLeft.y);
i++;
}
} catch (FingerException ex) {
Logger.getLogger(CallingID3Example.class.getName()).log(Level.SEVERE, null, ex);
}
gc = canvas.getGraphicsContext2D();
WritableImage writableImage = loadImage(source);
imageView.setImage(writableImage);
}
private WritableImage loadImage(Mat matrix) {
// Encoding the image
MatOfByte matOfByte = new MatOfByte();
Imgcodecs.imencode(".bmp", matrix, matOfByte);
// Storing the encoded Mat in a byte array
byte[] byteArray = matOfByte.toArray();
// Displaying the image
InputStream in = new ByteArrayInputStream(byteArray);
BufferedImage bufImage = null;
try {
bufImage = ImageIO.read(in);
} catch (IOException ex) {
}
// Creating the Writable Image
WritableImage writableImage = SwingFXUtils.toFXImage(bufImage, null);
return writableImage;
}
Thanks for your answer.
You could try something like this:
// You need to know width/height of the image
int width = 0;
int height = 0;
byte[] imageSrc = null;//
// Convert 8bit greyscale byte array to RGBA byte array.
byte[] imageRGBA = new byte[imageSrc.length * 4];
int i;
for (i = 0; i < imageSrc.length; i++) {
imageRGBA[i * 4] = imageRGBA[i * 4 + 1] = imageRGBA[i * 4 + 2] = ((byte) ~imageSrc[i]);
// Invert the source bits
imageRGBA[i * 4 + 3] = -1;// 0xff, that's the alpha.
}
// Convert RGBA byte array to PNG
int samplesPerPixel = 4;
int[] bandOffsets = {0,1,2,3}; // RGBA order
byte[] bgraPixelData = new byte[width * height * samplesPerPixel];
DataBuffer buffer = new DataBufferByte(bgraPixelData, bgraPixelData.length);
WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, samplesPerPixel * width, samplesPerPixel, bandOffsets, null);
ColorModel colorModel = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), true, false, Transparency.TRANSLUCENT, DataBuffer.TYPE_BYTE);
BufferedImage image = new BufferedImage(colorModel, raster, colorModel.isAlphaPremultiplied(), null);
System.out.println("image: " + image); // Should print: image: BufferedImage#<hash>: type = 0 ...
ImageIO.write(image, "PNG", new File(path));
Update
To draw rectangle on image:
BufferedImage image = ...
Graphics2D graph = img.createGraphics();
graph.setColor(Color.BLACK);
graph.fill(new Rectangle(x, y, width, height));
graph.dispose();
ImageIO.write(image, "PNG", new File(path));
Im having trouble finding a null pointer exception in some lejos code, which is for the EV3 lego robot.
Below is the class state and constructor:
public class Mapper {
private LineMap CurrentMap;
private Line[] lines;
private boolean[] userDrawn;
private Rectangle boundary = new Rectangle(0, 0, 594, 891);
private int counter;
/**
* Initializes an empty map with just a boundary
*
* #author Ben
*/
public Mapper(){
counter = 0;
lines = new Line[counter];
userDrawn = new boolean[counter];
CurrentMap = new LineMap(lines,boundary);
}
And the function causing me grief
public void addLine(float x1, float y1, float x2, float y2, boolean isUserDrawn){
counter++;
Line[] oldLines = lines;
boolean[] oldUserDrawn = userDrawn;
lines = new Line[counter];
userDrawn = new boolean[counter];
for(int i = 0; i < counter - 1; i++){
lines[i] = oldLines[i];
userDrawn[i] = oldUserDrawn[i];
}
lines[counter-1] = new Line(x1,y1,x2,y2);
if(isUserDrawn == true){
userDrawn[counter - 1] = true;
}
else{
userDrawn[counter - 1] = false;
}
CurrentMap = new LineMap(lines,boundary);
}
Any ideas for what might be a source of a null pointer exception:
Dont worry, problem not in this code. And has been solved.
This is my code :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;
import org.nocrala.tools.gis.data.esri.shapefile.ShapeFileReader;
import org.nocrala.tools.gis.data.esri.shapefile.ValidationPreferences;
import org.nocrala.tools.gis.data.esri.shapefile.exception.InvalidShapeFileException;
import org.nocrala.tools.gis.data.esri.shapefile.header.ShapeFileHeader;
import org.nocrala.tools.gis.data.esri.shapefile.shape.AbstractShape;
import org.nocrala.tools.gis.data.esri.shapefile.shape.PointData;
import org.nocrala.tools.gis.data.esri.shapefile.shape.shapes.PolygonShape;
public class MakeMap extends Application
{
static FileInputStream is;
static ShapeFileReader read;
static ShapeFileHeader head;
static AbstractShape shape;
static ValidationPreferences prefs;
static double minLat;
static double minLon;
static double maxLat;
static double maxLon;
static double ratio;
static double bMinLat;
static double bMinLon;
static double bMaxLat;
static double bMaxLon;
int gapx = 0, gapy = 0;
public void makeRatio(double lon_max, double lon_min, double lat_max, double lat_min)
{
double x, y; x = lon_max - lon_min;
y = lat_max - lat_min;
x = 600 / x;
y = 600 / y; if (x < y)
{
ratio = x;
gapy = (int) ((600 - (lat_max - lat_min) * x) / 2);
} else {
ratio = y; gapx = (int) ((600 - (lon_max - lon_min) * y) / 2); } }
public void assignBoundary(double min_lon, double max_lon, double min_lat, double max_lat)
{
minLon = coActLon(min_lon) * ratio; maxLon = coActLon(max_lon) * ratio; minLat = coActLat(min_lat) * ratio;
maxLat = coActLat(max_lat) * ratio;
}
public double coActLat(double p)
{
p = bMaxLat - p; return p;
}
public double coActLon(double p)
{
p = p - bMinLon; return p;
}
public int assignBoundaryLon(double p)
{
p = coActLon(p) * ratio - minLon; p += gapx;
return (int) p;
}
public int assignBoundaryLat(double p)
{
p = coActLat(p) * ratio;
p = p - maxLat; p += gapy;
return (int) p;
}
#Override public void start(Stage stage) throws Exception
{ File file = new File("/home/ranu/world.shp");
Canvas canvas = new Canvas(600, 600);
GraphicsContext gc = canvas.getGraphicsContext2D();
try
{
is = new FileInputStream(file);
}
catch (FileNotFoundException e)
{ // TODO Auto-generated catch block
e.printStackTrace();
} prefs = new ValidationPreferences();
prefs.setMaxNumberOfPointsPerShape(33200);
try
{
read = new ShapeFileReader(is, prefs);
}
catch (InvalidShapeFileException | IOException e)
{ // TODO Auto-generated catch block e.printStackTrace(); }
head = read.getHeader();
bMaxLon = head.getBoxMaxX();
bMinLon = head.getBoxMinX();
bMaxLat = head.getBoxMaxY();
bMinLat = head.getBoxMinY();
makeRatio(head.getBoxMaxX(), head.getBoxMinX(), head.getBoxMaxY(), head.getBoxMinY());
assignBoundary(head.getBoxMinX(), head.getBoxMaxX(), head.getBoxMinY(), head.getBoxMaxY());
gc.setFill(Color.rgb(53, 153, 255));
gc.fillRect(gapx, gapy, (maxLon - minLon), (minLat - maxLat));
drawShape(gc);
StackPane root = new StackPane();
root.getChildren().add(canvas);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public void drawShape(GraphicsContext gc) throws IOException, InvalidShapeFileException
{
int i = 0; gc.setFill(Color.WHITE);
gc.setStroke(Color.LIGHTGREY); gc.setLineWidth(1);
gc.strokeLine(10, 20, 30, 40);
Polygon polygon = new Polygon();
polygon.getPoints().add(new Double(20.0));
int count = 0;
double[] lat;
double[] lon;
Double[] data; gc.setStroke(Color.LIGHTGRAY);
while ((shape = read.next()) != null && count < 360)
{ // System.out.println(shape);
switch (shape.getShapeType())
{
case POINT: // PointShape aPoint = (PointShape) shape;
// Do something with the point shape... break;
case MULTIPOINT_Z: // MultiPointZShape aMultiPointZ = (MultiPointZShape) shape;
// Do something with the MultiPointZ shape... break;
case POLYGON: PolygonShape aPolygon = (PolygonShape) shape;
lat = new double[aPolygon.getNumberOfPoints()];
lon = new double[aPolygon.getNumberOfPoints()];
data = new Double[aPolygon.getNumberOfPoints() * 2];
int j = 0;
double x, y;
PointData[] point = aPolygon.getPoints();
for (i = 0; i < aPolygon.getNumberOfPoints(); i++)
{
x = point[i].getX();
y = point[i].getY();
j = 0; lat[j] = this.assignBoundaryLat(point[i].getY());
lon[j] = this.assignBoundaryLon(point[i].getX());
// data[j++] = new // Double(this.assignBoundaryLon(point[i].getX()));
// data[j] = new // Double(this.assignBoundaryLon(point[i].getY()));
for (j = j + 1, i = i + 1; (x != point[i].getX() || y != point[i] .getY()) && i < aPolygon.getNumberOfPoints(); i++, j++)
{
// lat[j] = this.assignBoundaryLat(point[i].getY());
// lon[j] = this.assignBoundaryLon(point[i].getX());
// data[j++] = new // Double(this.assignBoundaryLat(point[i].getX()));
// data[j] = new // Double(this.assignBoundaryLat(point[i].getY())); }
System.out.println(lat.length + " " + lon.length + " " + j);
// Polygon pg = new Polygon();
// pg.getPoints().addAll(data);
gc.strokePolygon(lon, lat, j);
System.out.println(count);
count ++; }
break; default: break; } } }
public static void main(String[] args)
{ Application.launch(args); }
Problem have in this code :
130 130 129
0
514 514 513
Exception in Application start method
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:403)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:47)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:115)
at java.lang.Thread.run(Thread.java:724)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 512
at javafx.scene.canvas.GraphicsContext.writePoly(GraphicsContext.java:326)
at javafx.scene.canvas.GraphicsContext.strokePolygon(GraphicsContext.java:1591)
at Experiment.MakeMap.drawShape(MakeMap.java:199)
at Experiment.MakeMap.start(MakeMap.java:129)
at com.sun.javafx.application.LauncherImpl$5.run(LauncherImpl.java:319)
at com.sun.javafx.application.PlatformImpl$5.run(PlatformImpl.java:216)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:179)
at com.sun.javafx.application.PlatformImpl$4$1.run(PlatformImpl.java:176)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$4.run(PlatformImpl.java:176)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:76)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:89)
... 1 more
https://drive.google.com/file/d/0B9nTZs5-E8czSEl4aXpwYjZhdUE/edit?usp=sharing world.shp
https://drive.google.com/file/d/0B9nTZs5-E8czT2RITnY5ZjFmTnM/edit?usp=sharing shapefilereader.jar
I have a text file where I get my values,
I have a timer which works as an increaser to the x axis so the plot is real time.
here's my code.
void gui::x()
{
int xy = 0;
QVector<double> x(1000), y(1000);
FILE *file;
char line[1024];
file = fopen("x.txt", "r");
while (fgets(line,1024,file) != NULL)
{
fscanf(file,"%lf %lf", &y[xy], &x[xy]);
xy++;
}
fclose(file);
QwtPlotCurve *curve = new QwtPlotCurve;
curve->attach(plot_all[3]);
curve->setData(y,x);
curve->
QwtPlotCurve *curve2 = new QwtPlotCurve;
curve2->attach(plot[3]);
curve2->setData(y,x);
}
the proble is i get a weird second line below my plot.
can anyone help me?
I solved it by using an array instead of a vector.
void gui::ecg()
{
int xy = 0;
double x[1000], y[1000];
FILE *file;
char line[1024];
file = fopen("ecg.txt", "r");
while (fgets(line,1024,file) != NULL)
{
fscanf(file,"%lf %lf", &y[xy], &x[xy]);
xy++;
}
fclose(file);
QwtPlotCurve *curve = new QwtPlotCurve;
curve->attach(plot_all[0]);
curve->setData(x,y,1000);
curve->setPen(QPen(Qt::blue,1));
QwtPlotCurve *curve2 = new QwtPlotCurve;
curve2->setStyle(QwtPlotCurve::Lines);
curve2->attach(plot[0]);
curve2->setData(x,y,1000);
curve2->setPen(QPen(Qt::blue,1));
}