Converting int[] to bytes[] Java - java
I am trying to convert an int[] to bytes . It gets converted also.
My code for conversion is this.
public static byte[] convertIntoBytes(int[] menuIds){
byte[] byteConverted;
ByteBuffer byteBuffer = ByteBuffer.allocate(menuIds.length * 4);
IntBuffer intBuffer = byteBuffer.asIntBuffer();
intBuffer.put(menuIds);
byteConverted = byteBuffer.array();
for (int i = 0; i < 840; i++) {
Log.d("Bytes sfter Insert", ""+byteConverted[i]);
}
return byteConverted;
}
Suppose i an inputting an int[] = {10,11,15,41,12,8,4,23,5,17,23,36,6}
Now i want the byte array to be like this
{10,0,0,0,11,0,0,0,15,0,0,0,41,0,0,0,12,0,0,0,8,0,0,0,4,0,0,0,23,0,0,0,5,0,0,0,17,0,0,0,23,0,0,0,36,0,0,0,6,0,0,0}
But the byte array coming to be is
{0,0,0,10,0,0,0,11,0,0,0,15,0,0,0,41,0,0,0,12,0,0,0,8,0,0,0,4,0,0,0,23,0,0,0,5,0,0,0,17,0,0,0,23,0,0,0,36,0,0,0,6,}
Actually i am trying to get the byte array to be start from first position.
try this
...
ByteBuffer byteBuffer = ByteBuffer.allocate(menuIds.length * 4);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
...
That depends on bits order on current machine.
Related
Best way to convert RGB byte[][] image to byte[]
Have frame data in the form of a byte[][] object, where each row corresponds to a (R,G,B) channel and is of length (frame width*frame height). I wish to convert it to a byte[] format in a similar vein as follows: byte[][] original_frame; byte[] converted_frame = convert(original_frame); ByteArrayInputStream bis = new ByteArrayInputStream(frame); BufferedImage bImage2 = ImageIO.read(bis); From what I can tell, ImageIO assumes a jpeg format. Do I need to convert every frame to a JPEG image, or is there a more natural way to do this?
I believe that you are asking how to convert from a 2D array to 1D array. How to do this if all rows are length 3 is as follows: ArrayList<byte> x = new ArrayList<byte>(); for(int i=0; i<original_frame.length; i++){ x.add(original_frame[i][0]); x.add(original_frame[i][1]); x.add(original_frame[i][2]); } byte[] converted_frame= new byte[x.size()]; for(int i=0;i<x.size();i++){ converted_frame[i]=x.get(i); } I hope this helps
Converting byte array to png
I have a byte array obtained from an image using the following code. String path = "/home/mypc/Desktop/Steganography/image.png"; File file = new File(path); BufferedImage bfimage = ImageIO.read(file); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(bfimage, "png", baos); baos.flush(); byte[] img_in_bytes = baos.toByteArray(); baos.close(); Then I converted these bytes back to png image using the following code. BufferedImage final_img = ImageIO.read(new ByteArrayInputStream(img_in_bytes)); File output_file = new File("Stegano2.png"); ImageIO.write(final_img, "png", output_file); It is perfectly fine if i just execute this piece of code. But if i try to modify some of the bytes in between, say like this : Insert_number_to_image(image_in_bytes, 10); and my method "Inset_number_to_image" goes like this : static void Insert_number_to_image(byte[] image, int size){ byte[] size_in_byte = new byte[4]; size_in_byte[0] = (byte)(size >>> 0); size_in_byte[1] = (byte)(size >>> 8); size_in_byte[2] = (byte)(size >>> 16); size_in_byte[3] = (byte)(size >>> 24); byte temp; int count = 0; for(int i=0; i<4; i++) { for(int j=0; j<8; j++) { temp = size_in_byte[i]; temp = (byte)(temp >>> j); temp = (byte)(temp & 1); if(temp == 1) { image[count] = (byte)(image[count] | 1); } else if(temp == 0) { image[count] = (byte)(image[count] & (byte)(~(1))); } count++; } } } then after that, when i save the modified byte array as png image using same code mentioned above, i am getting this error : Exception in thread "main" java.lang.IllegalArgumentException: image == null! at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925) at javax.imageio.ImageIO.getWriter(ImageIO.java:1591) at javax.imageio.ImageIO.write(ImageIO.java:1520) at Steganography.main(Steganography.java:211)
What you're using is the raw bytestream of a PNG image. PNG is a compressed format, where the bytestream doesn't reflect any of the pixel values directly and even changing one byte might irreversibly corrupt the file. What you want instead is to extract the pixel data to a byte array with byte[] pixels = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); Now you can modify the pixel values however you want. When you are ready to save that back to a file, convert the pixel byte array to a BufferedImage by putting your pixel array in a DataBufferByte object and passing that to a WriteableRaster, which you then use to create a BufferedImage. Your method would work for formats where the raw bytestream does directly represent the pixels, such as in BMP. However, even then you'd have to skip the first few bytes to avoid corrupting the header.
How to convert mat(OpenCV) to image(JavaFX)?
How to convert mat(OpenCV) to image(JavaFX)? I think this isn't not best method: MatOfByte byteMat = new MatOfByte(); Highgui.imencode(".bmp", mat, byteMat); return new Image(new ByteArrayInputStream(byteMat.toArray())); P.S. Image - import javafx.scene.image.Image;
One way to do it would be this.I do not remember the source from where I got this:- private Image mat2Image(Mat frame) { int type = BufferedImage.TYPE_BYTE_GRAY; if ( frame.channels() > 1 ) { type = BufferedImage.TYPE_3BYTE_BGR; } int bufferSize = frame.channels()*frame.cols()*frame.rows(); byte [] b = new byte[bufferSize]; frame.get(0,0,b); // get all the pixels BufferedImage image = new BufferedImage(frame.cols(),frame.rows(), type); final byte[] targetPixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); System.arraycopy(b, 0, targetPixels, 0, b.length); return SwingFXUtils.toFXImage(image,null); } There may be a way to make it neater using the Converters class from Opencv along with JDK8. I will update this if I find any such thing.
Paritosh, the issue with your method is that it only applies to the Mats with the type of CvType.CV_8U or CvType.CV_8S, since those Mats can be contained in a byte array. If the type of the Mat is, lets say, CvType.CV_32F, you would need a float array to hold the data. The float array cannot be System.arraycopied into a byte[] targetPixels array.
Convert ByteArrayOutputStream to int values
I am constantly trying to convert a ByteArrayOutputStream to int values. I am recording an Audio with microphone and writing it to out = new ByteArrayOutputStream() like so: out.write(buffer, 0, count); byte audio[] = out.toByteArray(); When I print this I get these : [B#3456337e How do I convert these to integer numbers. Please Help, Thanks
There is no standard way to do it because actually it depends on what kind of bytes you have but, as it is an audio source, I think you can do it like that : IntBuffer intBuf = ByteBuffer.wrap(byteArray) .order(ByteOrder.BIG_ENDIAN) //or try ByteOrder.LITTLE_ENDIAN .asIntBuffer(); int[] array = new int[intBuf.remaining()]; intBuf.get(array); //The result you want is "array" I hope it will help you.
Convert it to an array, wrap the array in a ByteArrayInputStream, wrap that in a DataInputStream, and use readInt().
Try the following - ByteArrayOutputStream out = new ByteArrayOutputStream(); DataInputStream dataIs = new DataInputStream (new ByteArrayInputStream(out.toByteArray()); // available stream to be read while(dataIs.available()>0) { int k = dataIs.readInt(); // print int System.out.print(k+" "); }
Java: retrieving byte array from an 8 bit wav file and normalizing it to -1.0 to 1.0
Bear with me as Im very new with working with audio and I have been googling for days for a solution and not finding any. So i retrieve the byte array of a .wav file with this (source: Wav file convert to byte array in java) ByteArrayOutputStream out = new ByteArrayOutputStream(); BufferedInputStream in = new BufferedInputStream(new FileInputStream(WAV_FILE)); int read; byte[] buff = new byte[1024]; while ((read = in.read(buff)) > 0) { out.write(buff, 0, read); } out.flush(); byte[] audioBytes = out.toByteArray(); And then i convert the byte array to a float array and normalize it from -1.0 to 1.0. (source: Convert wav audio format byte array to floating point) ShortBuffer sbuf = ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); short[] audioShorts = new short[sbuf.capacity()]; sbuf.get(audioShorts); float[] audioFloats = new float[audioShorts.length]; for (int i = 0; i < audioShorts.length; i++) { audioFloats[i] = ((float)audioShorts[i])/0x8000; } return audioFloats; Later i convert this to line drawings which outputs the waveform using java.swing class Panel2 extends JPanel { float[] audioFloats; Dimension d; public Panel2(Dimension d, float[] audioFloats) { // set a preferred size for the custom panel. this.d = d; setPreferredSize(d); this.audioFloats = audioFloats; } #Override public void paint(Graphics g) { //super.paintComponent(g); super.paint(g); //shift by 45 because first 44 bytes used for header for (int i = 45; i<audioFloats.length; i++){ Graphics2D g2 = (Graphics2D) g; float inc = (i-45)*((float)d.width)/((float)(audioFloats.length-45-1)); Line2D lin = new Line2D.Float(inc, d.height/2, inc, (audioFloats[i]*d.height+d.height/2)); g2.draw(lin); } } } The waveform only looks right for 16 bit wav files (ive cross checked with goldwave and both my waveform and their waveform look similar for 16 bits). How do i do this for 8 bit .wav files? Because this is for homework, my only restriction is read the wav file byte by byte. I also know the wav files are PCM coded and have the first 44 bytes reserved as the header
You need to adapt this part of the code: ShortBuffer sbuf = ByteBuffer.wrap(audioBytes).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); short[] audioShorts = new short[sbuf.capacity()]; sbuf.get(audioShorts); float[] audioFloats = new float[audioShorts.length]; for (int i = 0; i < audioShorts.length; i++) { audioFloats[i] = ((float)audioShorts[i])/0x8000; } You don't need ByteBuffer at all—you already have your byte array. So just convert it to floats: float[] audioFloats = new float[audioBytes.length]; for (int i = 0; i < audioBytes.length; i++) { audioFloats[i] = ((float)audioBytes[i])/0x80; }
Audio streams are usually interleaved with one channel of data then the opposite channel of data. So for example the first 16 bits would be the left channel, then the next 16 bits would be the right channel. Each of these is considered 1 frame of data. I would make sure that your 8 bit stream is only one channel because it looks like the methods are only set up to read one channel. Also in your example to convert the frames you are grabbing the individual channel as a short then finding a decimal by dividing that by 0x8000 hex or the maximum value of a signed short. short[] audioShorts = new short[sbuf.capacity()]; sbuf.get(audioShorts); ... audioFloats[i] = ((float)audioShorts[i])/0x8000; My guess is that you need to read the 8 byte stream as a type 'byte' instead of a short then divide that by 128 or the maximum value of a signed 8 bit value. This will involve making a whole new method that processes 8 bit streams instead of 16 bit streams. With the following changes. byte[] audioBytes = new byte[sbuf.capacity()]; sbuf.get(audioBytes); ... audioFloats[i] = ((float)audioBytes[i])/0x80;