I'm trying to create a game from scratch, and my question is directed towards the background image for that said game. This project is probably a precursor for me creating games on a greater scale. In this situation, I'm wanting to change the image it loads for the background depending on what room the game says its in. right now I have two room images, but I can't seem to get it to change the image after it has first been brought up. I don't want to load too big of a file and then use it like a sprite sheet, mainly because I don't want to have framerate issues in the future when the rooms get larger and there is a lot to load as well as the background. My question is, how do I change the image that the background will load in?
I have found several people with the same problem, and there may be answers to this question out there, but I am new-ish to programming so some of the language that is used might be foreign to me.
package com.game.main;
import java.awt.image.BufferedImage;
public class Texture {
SpriteSheet es, ps, ws, bg;
private BufferedImage enemy_sheet = null;
private BufferedImage player_sheet = null;
private BufferedImage weapon_sheet = null;
private BufferedImage background = null;
public BufferedImage[] enemy = new BufferedImage[2];
public BufferedImage[] player = new BufferedImage[9];
public BufferedImage[] weapon = new BufferedImage[9];
public String[] roomim = new String[9];
public BufferedImage room;
public Texture()
{
BuffImLoad loader = new BuffImLoad();
try{
enemy_sheet = loader.loadImage("/SpriteSheetEn1.png");
player_sheet = loader.loadImage("/SpriteSheet.png");
weapon_sheet = loader.loadImage("/SSWeapon.png");
int roomnum = Values.getRoomnum();
background = loader.loadImage(roomloader(roomnum));
}catch(Exception e){
e.printStackTrace();
}
es = new SpriteSheet(enemy_sheet);
ps = new SpriteSheet(player_sheet);
ws = new SpriteSheet(weapon_sheet);
bg = new SpriteSheet(background);
getTextures();
getRoom();
}
private void getTextures(){
enemy[0] = es.grabImage(1,1,56, 53);//idol en1
player[0] = ps.grabImage(1, 1, 34, 50);//temp player image
weapon[0] = ws.grabImage(1, 1, 7, 47);//temp player image
}
private void getRoom(){
room = bg.grabBG(0, 0, 3840 ,2160);
}
private String roomloader(int x){
roomim[0] = ("/Bgtemp.png");
roomim[1] = ("/Bgtemp2.png");
//roomim[1] =
return roomim[x];
}
}
Related
I have created an imgdb file consisting of images that I want to detect in arcore sceneform. Once I detect an image, I wish to display an augmented 3D object where the image was detected. Now, I wish to display a different 3D object depending on which image within the imgdb file was detected.
Something like this? But my app keeps crashing if I do this in the AugmentedImageNode.java file.
public class AugmentedImageNode extends AnchorNode {
private static final String TAG = "AugmentedImageNode";
public AugmentedImage image;
private static CompletableFuture<ModelRenderable> ulCorner;
public AugmentedImageNode(Context context) {
int imagenumber;
imagenumber = image.getIndex();
if (imagenumber == 0) {
if (ulCorner == null) {
ulCorner =
ModelRenderable.builder()
.setSource(context, Uri.parse("models/tinker.sfb"))
.build();
}
}
if (imagenumber == 1) {
if (ulCorner == null) {
ulCorner =
ModelRenderable.builder()
.setSource(context, Uri.parse("models/borderfence-small.sfb"))
.build();
}
}
}
Here are the logcat details:
enter image description here
i am learning to write code in java and recently started to write a game as per my assignment.
i have completed almost entire game but stuck with the animation part of the game.
here is what i have done so far,
this is the class that load the image ti display,
public class dpmImage {
private BufferedImage dpm1;
private BufferedImage setDpm1;
public dpmImage() { //this is a constructor
try {
dpm1= ImageIO.read(new File("dpm1Load.png"));
} catch (IOException e) {
e.printStackTrace();
}
setDpm1 = dpm1;
}
private BufferedImage dpm1ImageGet() {
return setDpm1;
}
}
the following code is from main class (Main.java)
private Graphics cGraphcs;
cGraphcs.drawImage(dpmImageInstance.dpm1ImageGet(), 0, 0, null);
The code is working fine and displays the image.
Now, I am allowed to modify anything in dpmImage class but not allowed to modify anything in Main.java and still make this image animate. So I create an array of BufferedImage in dpmImage class and add a second image in the array as follows,
public class dpmImage {
private BufferedImage [] dpm1 = new BufferedImage[2];
private BufferedImage setDpm1;
public dpmImage() { //this is a constructor
try {
dpm1[0]= ImageIO.read(new File("dpm1Load.png"));
dpm1[1]= ImageIO.read(new File("dpm1Load1.png"));
} catch (IOException e) {
e.printStackTrace();
}
setDpm1 = dpm1[0];
setDpm1 = dpm1[1];
}
private BufferedImage dpm1ImageGet() {
return setDpm1;
}
}
But i couldn't get to animate it from first image to 2nd. Can someone please give me any hints on that ? i am not allowed to change the Main.java class
You always return the same BufferedImage from the dpm1ImageGet method. You need to get the instance from the array. Based on the frequency of the update, you can simply use an index like
private int indexImage = 0;
private BufferedImage dpm1ImageGet() {
indexImage = ( indexImage + 1 ) % dpm1.length; //increment and use % to prevent any ArrayOutOfBoundsException
return dpm1[indexImage];
}
Each call will return the next image. Of course, this depends on when you want to get the other image. It could be anything.
How would I go about capturing an image for use in OpenCV from the standard camera module v2 plugged into a Raspberry Pi 3B? I've been trying to get high frame-rate video working, but using OpenCV's VideoCapture always gives me an empty Mat when I try to index device 0, and this and this both produced 1 frame per second or worse when I tried. I've also looked into spawning a raspivid process, but I don't see a way to get OpenCV's VideoCapture to read from the output of that process.
How would I get high FPS frame capture in Java? Is there a way I can get OpenCV to read from an OutputStream that I grab from another process?
EDIT: a simplified version of my code is below. I want to know how to populate the startRecording() function in this class
abstract class Main {
public static Mat currentCapture = null;
public static final double FOV_HEIGHT = 48.8;
public static final int WIDTH = 480;
public static final int HEIGHT = 384;
public static final int VIDEO_WIDTH = WIDTH * 2;
public static final int VIDEO_HEIGHT = HEIGHT * 2;
static {
System.loadLibrary(org.opencv.core.Core.NATIVE_LIBRARY_NAME);
}
public static void main(String[] args) {
client = new VisionClientTable("10.55.6.4", 5506);
new Thread(new VisionThread(VisionThread.Mode.VIDEO)).start();
new Thread(new VisionThread(VisionThread.Mode.TARGETING)).start();
}
private static class VisionThread implements Runnable {
private final Mode mode;
enum Mode {
VIDEO,
TARGETING
}
public VisionThread(Mode mode) {
this.mode = mode;
}
#Override
public void run() {
if (mode == Mode.TARGETING)
startTracking();
else if (mode == Mode.VIDEO)
startRecording();
}
}
public static void startTracking() {
/* this thread repeatedly captures currentCapture and processes it */
}
// this is where I need help
public static void startRecording() {
try {
VideoWriter video = new VideoWriter("/home/pi/vision/videos/video-" + Files.list(Paths.get("/home/pi/vision/captures")).count() + ".mp4", VideoWriter.fourcc('X', '2', '6', '4'), 30, new Size(VIDEO_WIDTH, VIDEO_HEIGHT), true);
VideoCapture capture = new VideoCapture(0);
capture.set(Videoio.CAP_PROP_FRAME_WIDTH, VIDEO_WIDTH);
capture.set(Videoio.CAP_PROP_FRAME_HEIGHT, VIDEO_HEIGHT);
Thread.sleep(2000);
while (true) {
long start = System.currentTimeMillis();
Mat mat = new Mat();
capture.read(mat);
if (!mat.empty()) { // mat is always empty
Mat downscaled = new Mat();
Imgproc.resize(mat, downscaled, new Size(WIDTH, HEIGHT), 0, 0, Imgproc.INTER_NEAREST);
currentCapture = downscaled;
}
video.write(mat);
long end = System.currentTimeMillis();
if (end - start < 1000 / 60)
Thread.sleep(1000 / 60 - (end - start));
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void log(String text) {
System.out.println(text);
}
}
I feel like the best way to do this might be to set raspivid to output to a file, and somehow feed the output of it into OpenCV, but I'm not sure how to do this.
EDIT 2: So far, I have tried using Runtime.getRuntime().exec() to run a raspivid command that outputs to a file, which works, but then when I try to open that file with OpenCV, capture.isOpened() remains false, even as the program repeatedly tries to open the file.
not getting much idea about your code from your question.
following may help you.
http://bigdinotech.com/tutorials/beaglebone-black-tutorials/building-opencv-on-the-beaglebone-black-or-raspberry-pi/
I'm trying to make a program that takes a picture from a webcam, and afterwards resizes it, converts it to HSV, and makes some thresholding on it, to find a specific color. After this is done, I use the thresholded image to find contours, and print the x,y coords of the different contours. This is repeated over and over, to make the processing from the webcam realtime.
It all works quite well, except for the fact that I am using up about 100 mb of RAM every 2 second it runs.
So far I have discovered that if I use a static picture, instead of the live images from the webcam, I can minimize the memory leak significantly, although still there is memory being consumed.
Below my code is:
public class Application {
private CaptureImage ci;
private ImageUtils iu;
private CanvasFrame canvasContours;
IplImage grabbedFrame;
IplImage resizedFrame;
IplImage thresholdedFrame;
IplImage clonedImage;
public Application(){
ci = new CaptureImage();
iu = new ImageUtils();
canvasContours = new CanvasFrame("contours");
}
public void frameProcessing(){
grabbedFrame = ci.grabImage();
//below call used for testing purposes
//grabbedFrame = (IplImage) opencv_highgui.cvLoadImage("testingImage.jpg");
//cloning image due to highgui guidelines.
clonedImage = opencv_core.cvCloneImage(grabbedFrame);
resizedFrame = iu.resizeImage(clonedImage);
opencv_core.cvReleaseImage(clonedImage);
thresholdedFrame = iu.thresholdImage(resizedFrame);
IplImage contoursFrame = iu.findContours(thresholdedFrame, resizedFrame);
canvasContours.showImage(contoursFrame);
}
}
The grabImage is just the standard frameGrabber from javacv, which looks like this:
public class CaptureImage {
private final OpenCVFrameGrabber grabber;
private IplImage img = null;
public CaptureImage(){
// 0-default camera, 1 - next...so on
grabber = new OpenCVFrameGrabber(0);
try {
grabber.start();
} catch (Exception e) {
System.err.print("Failed to initialize camera");
e.printStackTrace();
}
}
public IplImage grabImage(){
try {
//A grabbed image from Logitech webcam is in following resolution: 1200x800px
img = grabber.grab();
} catch (Exception e) {
e.printStackTrace();
}
return img;
}
I appreciate any help you can give me, and if you need any more information, please just ask!
/Jesper
From your heap dump, the used memory is all byte and int arrays that are referenced from native code. Looking at your code I see that you only call cvReleaseImage for the cloned image and not for the original image.
it gives me a black screen for setbackground,
but it doesnt seem to read the images or draw them,
some help would be appreciated, also if you could tell me the information
pertaining to my code, i have trouble understanding general
r vague answers, thanks.
import java.awt.*;
import javax.swing.*;
import javax.swing.JComponent.*;
public class Movie extends JApplet {
private String movName1;
private String director1;
private int yearMade1;
private Image movPic1;
private String movName2;
private String director2;
private int yearMade2;
private Image movPic2;
private String movName3;
private String director3;
private int yearMade3;
private Image movPic3;
private String movName4;
private String director4;
private int yearMade4;
private Image movPic4;
public void init() {
MovieDis goo = new MovieDis(movPic1, movPic2, movPic3, movPic4);
goo.setBounds(0, 0, 750, 500);
add(goo);
}
}
class MovieDis extends JComponent {
private String movName1;
private String director1;
private int yearMade1;
private Image movPic1;
private String movName2;
private String director2;
private int yearMade2;
private Image movPic2;
private String movName3;
private String director3;
private int yearMade3;
private Image movPic3;
private String movName4;
private String director4;
private int yearMade4;
private Image movPic4;
public MovieDis(Image movPic1, Image movPic2, Image movPic3, Image movPic4) {
setBackground(Color.black);
movPic1 = Toolkit.getDefaultToolkit().createImage("Shaw.jpg");
movPic2 = Toolkit.getDefaultToolkit().createImage("dances.jpg");
movPic3 = Toolkit.getDefaultToolkit().getImage("Inception.jpg");
movPic4 = Toolkit.getDefaultToolkit().getImage("Cuckoo.jpg");
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.black);
g.fillRect(0, 0, 750, 500);
g.drawImage(movPic1, 35, 35, 200, 200, this);
g.drawImage(movPic2, 35, 515, 200, 200, this);
g.drawImage(movPic3, 265, 35, 200, 200, this);
g.drawImage(movPic4, 35, 515, 200, 200, this);
}
}
From what i can see, most likely your images are null or empty. Seeing how this is applet code and you're not using proper URLs, the Toolkit will likely return a sentinel value (an image with width and height = -1) if it can't locate the images. Unfortunately, g.drawImage will not throw an exception in this case. Please check that your images are loaded correctly.
There are a lot of reason this might not work, the most obvious are
You don't have permission to read the images (either of the file system or the URL)
The URL reference is wrong (because the location of the files are not where you think they are)
Depending on where the files are stored, you have two choices.
If the files are stored on the server, along with the Jar. You will need to know the document base reference.
So in your init method, you'll need add
URL base = getDocumentBase();
System.out.println("base = " + base); // testing only
movPic1 = getImage(base, "issue169.jpg");
movPic2 = getImage(base, "issue194.jpg");
movPic3 = getImage(base, "issue248.jpg");
movPic4 = getImage(base, "issue78.jpg");
This assumes that the images reside in the same directory on the server as the HTML file. You can use relative paths as needed.
If the files are stored/bundled in the Jar (this is probably the preferred way for static images), you need to use the classloader to find them
try {
movPic1 = ImageIO.read(getClass().getResource("/testapplet/issue169.jpg"));
movPic2 = ImageIO.read(getClass().getResource("/testapplet/issue194.jpg"));
movPic3 = ImageIO.read(getClass().getResource("/testapplet/issue248.jpg"));
movPic4 = ImageIO.read(getClass().getResource("/testapplet/issue78.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
I used this method but did run into a small problem while testing. Because my files handed been bundled (yet), the applet viewer was trying to load them as a File reference which it didn't have permission to do - the applet view allows you to set it as unrestricted.
This eventually resulted in
PS- I set the applets layout manager to BorderLayout rather then using absolute positioning.