I've been trying to load a bmp picture to use it as a texture at my program I've used a IOStream class to extend DataInputStream to read the pixels at the photo with this code based on a texture loader code for C++:
//class Data members
public static int BMPtextures[];
public static int BMPtexCount = 30;
public static int currentTextureID = 0;
//loading methode
static int loadBMPTexture(int index, String fileName, GL gl)
{
try
{
IOStream wdis = new IOStream(fileName);
wdis.skipBytes(18);
int width = wdis.readIntW();
int height = wdis.readIntW();
wdis.skipBytes(28);
byte buf[] = new byte[wdis.available()];
wdis.read(buf);
wdis.close();
gl.glBindTexture(GL.GL_TEXTURE_2D, BMPtextures[index]);
gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, 3, width, height, 0, GL.GL_BGR, GL.GL_UNSIGNED_BYTE, buf);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
currentTextureID = index;
return currentTextureID;
}
catch (IOException ex)
{
// Utils.msgBox("File Error\n" + fileName, "Error", Utils.MSG_WARN);
return -1;
}
}
and IOStream code :
public class IOStream extends DataInputStream {
public IOStream(String file) throws FileNotFoundException {
super(new FileInputStream(file));
}
public short readShortW() throws IOException {
return (short)(readUnsignedByte() + readUnsignedByte() * 256);
}
public int readIntW() throws IOException {
return readShortW() + readShortW() * 256 * 256;
}
void read(Buffer[] buf) {
}
}
and the calling:
GTexture.loadBMPTexture(1,"/BasicJOGL/src/basicjogl/data/Font.bmp",gl);
after debugging I figured out that when it come to this line:
IOStream wdis = new IOStream(fileName);
an IOExeption occurred and it's a DispatchException What's this supposed to mean, and how can I solve it?
I tried to:
use \ and \\ and / and //
change the path of the photo and take all the path from c:\ to the photoname.bmp
rename the photo using numbers like 1.bmp
None worked.
Judging by your latest comment, you are no longer getting the IOException but are still having troubles getting the texture to actually render (just getting a white square).
I noticed the following are not in the code you posted here (but could be elsewhere):
gl.glGenTextures
You need to generate places for your textures before binding them. Also, make sure you have enabled texturing:
gl.glEnable(GL.GL_TEXTURE2D);
For additional information / tutorials on getting started with OpenGL texturing, I recommend taking a read of NeHe Productions: OpenGL Lesson #06. Also, down the bottom of the page you will find JOGL sample code to help you convert the concepts from C to Java.
Anyway, hope this gives a few new ideas to try.
Probably don't need help on this anymore, but I noticed that IOStream extends DataInputStream but when it comes to actually implementing read() it's been left blank. so regardless you're never actually reading anything into buf which might explain why your texture is blank but you don't get any other problems.
Here is a simple way of loading a texture in JOGL. It works with BMP as well.
public static Texture loadTexture(String file) throws GLException, IOException
{
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(ImageIO.read(new File(file)), "png", os);
InputStream fis = new ByteArrayInputStream(os.toByteArray());
return TextureIO.newTexture(fis, true, TextureIO.PNG);
}
also dont forget to enable and bind, and set texture-coordinates.
...
gl.glEnableClientState(GL2ES1.GL_TEXTURE_COORD_ARRAY);
if(myTexture == null)
myTexture = loadTexture("filename.png");
myTexture.enable(gl);
myTexture.bind(gl);
gl.glTexCoordPointer(2, GL2ES1.GL_FLOAT, 0, textureCoords);
...
Related
This code works, it reads a file in byte type and after assigning the image it creates a copy in the directory where the other part is located with a different name, I must do the same, create a new file, I just have to make it rotate on the X and Y axes as the final 180 degree image without creating a library to do the job.
Can you help me with the code or madnar information
Thank you!
public class BMPRotations {
public static void main(String[] args) throws IOException {
int contador=0;
int datos_entrada[] = new int[921655];
try {
FileInputStream archivo_lectura = new FileInputStream("Ruta__picture.bmp");
boolean final_ar = false;
while(!final_ar) {
int byte_entrada = archivo_lectura.read();
if(byte_entrada!=-1)
datos_entrada[contador]=byte_entrada;
else
final_ar=true;
//Muestra todos los bytes
//System.out.println(datos_entrada[contador]);
contador++;
}
archivo_lectura.close();
}catch(IOException e) {
System.out.print("Error");
}
System.out.print("Bystes de la imagen: " + contador);
crea_fichero(datos_entrada);
}
static void crea_fichero(int datos_nuevo_fichero[]) {
try {
FileOutputStream fichero_nuevo = new FileOutputStream("Ruta_picture.bmp");
for(int i=0; i<datos_nuevo_fichero.length;i++) {
fichero_nuevo.write(datos_nuevo_fichero[i]);
}
fichero_nuevo.close();
}catch(IOException e) {
System.out.println("Error ");
}
}
Here is a reference image.
640X480 in 24-bit format
https://i.stack.imgur.com/pz4A4.png
This isn't a full answer but I hope it points you in right direction for what looks like homework.
What you have implemented so far is simply copying a file with hard-coded size 921655, and does not deal with an image - just any file. You could replace the entire program with:
File input = new File("Ruta__picture.bmp");
File output = new File("Ruta_picture.bmp");
Files.copy(input.toPath(), output.toPath(), StandardCopyOption.REPLACE_EXISTING);
To deal with images, look at javax.imageio.ImageIO class. This shows how to load any supported JDK image type and write it back:
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
BufferedImage image = ImageIO.read(input);
// TODO: TRANSFORM "image" here
BufferedImage modified = image;
ImageIO.write(modified , "bmp", output);
Note that ImageIO.write supports other types such as "jpg".
This post is a follow up to :
ImageIO.read can't read ByteArrayInputStream (image processing)
Similar to the OP, I am getting a null pointer whenever I try to read from my ByteArrayInputStream (as it should, as explained by the top answer). Noticing this, I have implemented the code from the #haraldK 's answer from the post above in order to correct this issue, but I have run into another problem. I have the following code:
byte[] imageInByteArr = ...
// convert byte array back to BufferedImage
int width = 1085;
int height = 696;
BufferedImage convertedGrayScale = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
convertedGrayScale.getRaster().setDataElements(0, 0, width, height, imageInByteArr );
try {
ImageIO.write(convertedGrayScale, "jpg", new File("C:\\test.jpg"));
}
catch (IOException e) {
System.err.println("IOException: " + e);
}
Upon execution, I run into a java.lang.ArrayIndexOutOfBoundsException: null error on the line right before the try/catch block. My first thought was that this null pointer was arising for not having a file in my C drive called test.jpg. I adjusted to fix that worry, yet I am still getting the same null pointer issue at convertedGrayScale.getRaster().setDataElements(0, 0, width, height, imageInByteArr );. Why is this happening?
On another note, aside from writing the file uining ImageIO, is there ANY other way for me to convert the byte[] into a visual representation of an image? I have tried to just print the array onto a file and saving it as a '.jpg', but the file will not open. Any suggestions will help. To summarize, I am looking to convert a byte[] into an image and save it OR render it onto a browser. Whichever is easier/doable.
it appears that your imageInByteArr is too short. I was able to get the same error you get from this
public static void main(String[] args) {
int width = 1085;
int height = 696;
byte[] imageInByteArr = new byte[width ];
BufferedImage convertedGrayScale = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
convertedGrayScale.getRaster().setDataElements(0, 0, width, height, imageInByteArr);
}
when using width*height for size of imageInByteArr or anything bigger i get no error, but when it's smaller than the data you are trying to update it throws the exception.
I'm currently working on a dynamic Animation Loader for Characters in a game and for that I'm in need of detecting if the current frame is completely blank in order to stop loading more sprites.
This is what I'm currently using to find out if the current image is blank:
public static boolean isBlankImage(BufferedImage b) {
byte[] pixels1 = getPixels(b);
byte[] pixels2 = getPixels(getBlankImage(b.getWidth(), b.getHeight()));
return Arrays.equals(pixels1, pixels2);
}
private static BufferedImage getBlankImage(int width, int height) {
return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
}
private static byte[] getPixels(BufferedImage b) {
byte[] pixels = ((DataBufferByte) b.getRaster().getDataBuffer()).getData();
return pixels;
}
However, as soon as I run it, I get this annoying error:
Exception in thread "Thread-0" java.lang.ClassCastException:
java.awt.image.DataBufferInt cannot be cast to java.awt.image.DataBufferByte
I've tried switching the casting type but all I get in return is:
Exception in thread "Thread-0" java.lang.ClassCastException:
java.awt.image.DataBufferByte cannot be cast to java.awt.image.DataBufferInt
I've searched all over the place for an answer to no avail, so here's my question: Is there a better functional way to check if an image is fully transparent ?
Any help will be greatly appreciated.
The method must be return a byte array, you are trying convert a DataBuffer in a DataBufferByte.
I have changed the name getPixels to getByteArray. Since it is not the same.
Try this:
private static byte[] getByteArray(BufferedImage img) {
byte[] imageInByte = null;
String format = "jpeg"; //Needs a image TYPE
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, format, baos);
baos.flush();
imageInByte = baos.toByteArray();
baos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return imageInByte;
}
The blank image's DataBuffer is indeed an instance of DataBufferInt while your original image has a buffer of type DataBufferByte.
You should create your empty image based on the type of the image to compare with:
private static BufferedImage getBlankImage(int width, int height, int type) {
return new BufferedImage(width, height, type);
}
and call it this way:
getBlankImage(b.getWidth(), b.getHeight(), b.getType())
Notice that in terms of performance and memory usage it may be better to create the empty image only once (or once for each image type which may occur).
Probably the image type and size are constant and written wherever the actual images are created.
Now you have a proper empty image and may test its equality as in Is there a simple way to compare BufferedImage instances?:
public static boolean compareImages(BufferedImage imgA, BufferedImage imgB) {
int width = imgA.getWidth();
int height = imgA.getHeight();
// Loop over every pixel.
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// Compare the pixels for equality.
if (imgA.getRGB(x, y) != imgB.getRGB(x, y)) {
return false;
}
}
}
return true;
}
Does anybody knows how to use a wavelet transform (Haar or Daubechies) of BoofCV in Java?
There's no code example on the web and I'm very new at this library.
I've tried this code below, but so for no results.
public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException {
String dir = "C:\\Users\\user\\Desktop\\ImgTest\\";
BufferedImage buff =UtilImageIO.loadImage(dir+"img.png");
ImageUInt16 aux = UtilImageIO.loadImage(dir+"img.png", ImageUInt16.class);
ImageSInt16 input = new ImageSInt16(aux.width, aux.height);
input =ConvertImage.convert(aux, input);
ImageSInt32 output = new ImageSInt32(aux.width, aux.height);
int minPixelValue = 0;
int maxPixelValue = 255;
WaveletTransform<ImageSInt16, ImageSInt32, WlCoef_I32> transform =
FactoryWaveletTransform.create_I(FactoryWaveletHaar.generate(true, 0), 1,
minPixelValue, maxPixelValue,ImageSInt16.class);
output=transform.transform(input, output);
//BufferedImage out = ConvertBufferedImage.convertTo(output, null);
BufferedImage out = new BufferedImage(input.width*6, input.height*6, 5);
out = VisualizeBinaryData.renderLabeled(output, 0, out);
ImageIO.write(out, "PNG", new File(dir+"out.png"));
}
}
I also tried JWave, but there's no code example either and the responsible wasn't able to help with it.
Thank you!
There are a lot of code examples outside there. I made one before, but in C# not Java. For Java Code, you could refer to here
I have a Canvas I draw on, I'm trying to take the bitmap out, convert it to a byte array and save it serialized into a file. then later open, deserialize, and apply the bitmap back to the canvas. In the code below everything seems to work well except that when applying the bitmap to canvas nothing appears. can someone please show me where I'm going wrong.
public byte[] getCanvasData(){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
mBitmap.compress(CompressFormat.PNG, 0, bos);
byte[] bitmapdata = bos.toByteArray();
return bitmapdata;
}
public void setCanvasData(byte[] canvasData, int w, int h){
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(0x00000000);
mCanvas = new Canvas(mBitmap);
mCanvas.drawBitmap(BitmapFactory.decodeByteArray(canvasData , 0, canvasData.length).copy(Bitmap.Config.ARGB_8888, true), 0, 0, null);
}
ADDED SOME EXTRA CODE TO POSSIBLY HELP A LITTLE
public void readInSerialisable() throws IOException
{
FileInputStream fileIn = new FileInputStream("/sdcard/theBKup.ser");
ObjectInputStream in = new ObjectInputStream(fileIn);
try
{
BookData book = (BookData) in.readObject();
pages.clear();
canvasContainer.removeAllViews();
for (int i = 0; i < book.getBook().size(); i++){
Log.d("CREATION", "LOADING PAGE " + i);
pages.add(new Canvas2(context, book.getPageAt(i), canvasContainer.getWidth(), canvasContainer.getHeight()));
}
canvasContainer.addView(pages.get(page), new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, AbsoluteLayout.LayoutParams.FILL_PARENT, 0, 0));
updatePagination();
Log.d("CREATION", "Updated Pagination");
}
catch (Exception exc)
{
System.out.println("didnt work");
exc.printStackTrace();
}
}
BookData - Serializable class containing all my data, simple gets/sets in there
onDraw Method
#Override
protected void onDraw(Canvas canvas) {
Log.d("DRAWING", "WE ARE DRAWING");
canvas.drawColor(0x00AAAAAA); //MAKE CANVAS TRANSPARENT
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
I would do the following 2 tests.
Log some of the byte stream to make sure that it was loaded correctly. Something like Log.v(canvasData[0]+canvasData[1]);, or put a break point there, or something just to make sure the data is correct.
Draw a bitmap that you know is valid, using the same code, and see if it appears correctly.
I'm not sure exactly what's going on, but I strongly suspect one of the following.
The byte stream is not being read in correctly.
The bitmap is not being updated to the screen, or is using a trivially small size.
In the event that your byte stream data has something, then you will want to take a look at the Canvas documentation. Specifically, look at the following bit.
In order to see a Canvas, it has to be put on to a view. Once it is on a view, the onDraw() command must be called for it to be visible. I would make sure that you are in fact doing an onDraw(), and that the Canvas is associated with the View correctly. If you are using an onDraw() already, please post the bits of code associated with it.