Image loads; Cannot put into array
This loads just fine:
private Mat m = Imgcodecs.imread("C:/Users/Link/workspace/G3DExperiment/src/imgres/stone.png");
But for some reason I can't load it into an array:
public void draw(Mat mat, int x, int y) {
int rows = mat.rows(), cols = mat.cols(), type = CvType.channels(mat.type());
int[] bgr = new int[rows*cols*type];
mat.get(0, 0, bgr);
canvas.setRGB(x, y, cols, rows, bgr, 0, width);
}
canvas
is a BufferedImage of type TYPE_3BYTE_BGR and this method MatrixCanvas#draw(Mat, int, int)
is used to draw a Mat directly onto the screen by covering the screen in a BufferedImage and setting the pixels on the image.
The full stacktrace reads:
Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException: Mat data type is not compatible: 16
at org.opencv.core.Mat.get(Mat.java:2599)
at genesis.g2D.MatrixCanvas.draw(MatrixCanvas.java:158)
at g.Main.<init>(Main.java:49)
at g.Main.<init>(Main.java:42)
at g.Main$1.run(Main.java:37)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
try
byte[] bgr = new byte[mat.total() * mat.elemSize()];
( not int)Yeah I probably should try byte. int didn't work. It still gives an error.
hehe, you can do it all in 2 lines:
Your optimization makes it 1 line for my method. Also, it works! I mean it doesn't draw correctly, but it works! Probably a problem somewhere between types but... it works! Thanks again :)
ah ok. i'm cheating, that's 3 lines more :
now look here - i guess, now you can make a much better answer, than the existing one !
That is too CPU intensive to run at 60 fps. I need a one-liner that will set the data in a BufferedImage that is the size of the JFrame it is in. Currently, your
m.get(0,0,((DataBufferByte)image.getRaster().getDataBuffer()).getData());
works, but it shows up as two rows of pixels rather than an image. I need the fastest way to copy data from a Mat into what is now a TYPE_4BYTE_ABGR. I changed the type to allow alpha. I noticed the methodBufferedImage.getRaster().setPixels(x, y, w, h, iArray);
which sets a part or the whole thing to some pixels. Simply using setPixels(x, y, Raster) would just copy the pixels in without formation and so that is why it is two lines instead of 16x16.Or something fast enough that it isn't one line, but does not use condition statements. To clarify, the canvas can only be instantiated as
new MatrixCanvas() {... TYPE_4BYTE_ABGR ...}
if your canvas has to be bgra, then
Imgproc.cvtColor(img,img,COLOR_BGR2BGRA);
andtype = BufferedImage.TYPE_3BYTE_BGRA
Well, That converts it to BGRA, but if I load the image using
Imgcodecs.imread(imgname, Imgcodecs.IMREAD_UNCHANGED)
, that should load unchanged, as in the actual read in data right? Also, I still need a way to efficiently copy the data in one swift move.