Java Corrupt JPEG data ... sending image Client-Server-Client - java

My error when sending an image Client-Server-Client is "Corrupt JPEG data: 4350674 extraneous bytes before marker 0xd9" What I can change? Here is my code :
SERVER
InputStream is = klienciRemoteScreen[1].getInputStream();
OutputStream os = klienciRemoteScreen[0].getOutputStream();
byte[] bytesize = new byte[4];
is.read(bytesize);
int size = ByteBuffer.wrap(bytesize).asIntBuffer().get();
byte [] image= new byte [size];
byte[]bufferimage = new byte [1];
os.write(bytesize);
os.flush();
int count;
while((count = is.read(image)) > 0)
{
os.write(image);
os.flush();
}
os.close();
CLIENT sending image to server
OutputStream os = noguiklient.sockRemoteScreen.getOutputStream();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
Rectangle rectangle = new Rectangle(dim);
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(rectangle);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", byteArrayOutputStream);
byte[] size =
ByteBuffer.allocate(4).putInt(byteArrayOutputStream.size()).array();
int sizeas = ByteBuffer.wrap(size).asIntBuffer().get();
os.write(size);
os.write(byteArrayOutputStream.toByteArray());
os.close();
CLIENT Receiving from server
JFrame okno = new JFrame();
okno.setSize(1300, 1000);
okno.setTitle(" Remote screen");
okno.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel();
panel.setSize(1300,1000);
panel.setLayout(null);
okno.add(panel);
okno.setVisible(true);
InputStream is = Klient.sockRemoteScreen.getInputStream();
File photo = new File ("photo") ;
FileOutputStream fos = new FileOutputStream(photo);
byte[] buffer = new byte[4];
is.read(buffer);
int size = ByteBuffer.wrap(buffer).asIntBuffer().get();
byte[] image = new byte [size];
int count;
int i =0 ;
while((count = is.read(image)) > 0)
{
fos.write(image);
fos.flush();
}
ImageIcon screen = new ImageIcon("photo");
Image imagefinal = screen.getImage();
imagefinal =
imagefinal.getScaledInstance(okno.getWidth(),okno.getHeight(), Image.SCALE_SMOOTH);
BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
Graphics graphics = panel.getGraphics();
while(true)
{
graphics.drawImage(imagefinal, 0, 0, panel.getWidth(), panel.getHeight(), panel);
}
Example of this bad Image
When I try to send with ImageIO everything is fine but I want to try with bytes and there is a problem.
Thank you :)

Related

Image transfering btween JavaFX and Android via Bluetooth

I'm trying implement a simple file transfering app.
My app does like that:
1. Capture current camera preview in Android
2. Send it to Javafx application via Bluetooth
3. When Javafx app received the image saving it and show on the window
4. After some drawing over the image capture it then send it to Android again
I implemented like this on Android side first
I created a kind of packet which contains file size, actual data and eof.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
data.compress(Bitmap.CompressFormat.JPEG, 100, baos);
// filesize + data + end of file
String fileSize = String.valueOf(baos.size());
fileSize += '\0'; // end of the filesize string
String eof = "eof"; // end of packet
// set packet size
int packetSize = fileSize.length() + baos.size() + eof.length();
ByteBuffer byteBuffer = ByteBuffer.allocate(packetSize);
byteBuffer.put(fileSize.getBytes());
byteBuffer.put(baos.toByteArray());
byteBuffer.put(eof.getBytes());
byte[] data = new byte[byteBuffer.capacity()];
byteBuffer.position(0);
byteBuffer.get(data);
and send the data to bluetooth outputstream socket
On JavaFX side,
bytes = btIn.read(buffer);
// receive packet data
if (fileSize == null) {
for (int i = 0; i < bytes; i++) {
if (buffer[i] == '\0') {
fileSize = new String(buffer, 0, i);
break;
}
}
}
// eof offset
int offset = bytes - 3;
byte[] eofByte = new byte[3];
eofByte = Arrays.copyOfRange(buffer, offset, bytes);
String message = new String(eofByte, 0, 3);
if (message.equals("eof")) {
eof = true;
fos.write(buffer, 0, bytes-3);
} else {
// set buffer size to file size
if (fileBuffer == null) {
fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize));
fileBuffer.put(buffer, fileSize.length()+1, bytes);
fos.write(buffer, fileSize.length()+1, bytes);
} else {
fileBuffer.put(buffer, 0, bytes);
fos.write(buffer, 0, bytes);
// for progress bar
percent = (float) fileBuffer.position() / (float) fileBuffer.capacity();
}
}
log(String.valueOf(percent));
if (eof) {
byte[] data = new byte[fileBuffer.capacity()];
fileBuffer.position(0);
fileBuffer.get(data);
ByteArrayInputStream input = new ByteArrayInputStream(data);
bufferedImage = ImageIO.read(input);
image = SwingFXUtils.toFXImage(bufferedImage, null);
if (bufferedImage != null) {
log("got the image");
}
// set null fileBuffer and fileSize for next images
fileSize = null;
fileBuffer = null;
}
}
above code is for receving image from the Anroid
and Sending part on JavaFX is:
WritableImage writableImage = new WritableImage((int)canvas.getWidth(), (int)canvas.getHeight());
canvas.snapshot(null, writableImage);
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(writableImage, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write(bufferedImage, "jpg", baos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] imageInBytes = baos.toByteArray();
log(String.valueOf(imageInBytes.length));
bct.write(imageInBytes);
String eof = "end of file";
byte[] eofbyte = eof.getBytes();
bct.write(eofbyte);
the sending and receiving part work fine..
But I have problems on result images
This is JavaFX side when received the image from Android and ss you see, the most left side of the image is not desired
and more weired after receving image from JavaFX side the result image on Android like this:
My question is how should I fix the code to get correct images?
I think you were hit by this bug:
https://bugs.openjdk.java.net/browse/JDK-8041459
You can avoid this problem by using PNG instead of JPG. Another option is to explicitly convert the image into an image without alpha component before storing it.
Michael

How to make an exact copy of image in java?

After loading the image, I want to create an exact copy of the image whereby the quality and scale can remain the same. With my current code, the quality was reduced.
public class Image {
private static final String path = "C:/Users.../src/7horses.jpg";
private static final File file = new File(path);
static BufferedImage deepCopy(BufferedImage bi) throws IOException {
String saveAs = "copy.jpg";
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
BufferedImage cImg = new BufferedImage(cm, raster, isAlphaPremultiplied, null);
File saveImage = new File("C:/Users.../src", saveAs);
ImageIO.write(cImg, "jpg", saveImage);
return cImg;
}
public static void main(String[] args) throws IOException {
BufferedImage cp, img;
img = ImageIO.read(file);
cp = deepCopy(img);
}
}
try just to copy your image file, use this code :
InputStream is = null;
OutputStream os = null;
try {
is = new FileInputStream(new File("path/to/img/src"));
os = new FileOutputStream(new File("path/to/img/dest"));
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
} finally {
is.close();
os.close();
}
if you are using Java 8 then you can just call Files.copy method, check it in the docs
Go from using:
ImageIO.write(cImg, "jpg", saveImage);
To the following: (Don't have my dev environment here to test this but think I have this close for you.)
Iterator iterator = ImageIO.getImageWritersByFormatName("jpeg");
ImageWriter writer = (ImageWriter)iterator.next();
ImageWriteParam imageWriteParam = writer.getDefaultWriteParam();
imageWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
imageWriteParam.setCompressionQuality(1); //0 is max Compression 1 is max quality
FileImageOutputStream output = new FileImageOutputStream(saveImage);
writer.setOutput(output);
IIOImage image = new IIOImage(cImg, null, null);
writer.write(null, image, iwp);
writer.dispose();
output.close();

How to create an image from an InputStream, resize it and save it?

I have this code where i get an InputStream and create an image:
Part file;
// more code
try {
InputStream is = file.getInputStream();
File f = new File("C:\\ImagenesAlmacen\\QR\\olaKeAse.jpg");
OutputStream os = new FileOutputStream(f);
byte[] buf = new byte[1024];
int len;
while ((len = is.read(buf)) > 0) {
os.write(buf, 0, len);
}
os.close();
is.close();
} catch (IOException e) {
System.out.println("Error");
}
The problem is that I have to resize that image before i create if from the InputStream
So how to resize what I get from the InputStream and then create that resized image. I want to set the largest side of the image to 180px and resize the other side with that proportion.
Example:
Image = 289px * 206px
Resized image = 180px* 128px
I did this:
try {
InputStream is = file.getInputStream();
Image image = ImageIO.read(is);
BufferedImage bi = this.createResizedCopy(image, 180, 180, true);
ImageIO.write(bi, "jpg", new File("C:\\ImagenesAlmacen\\QR\\olaKeAse.jpg"));
} catch (IOException e) {
System.out.println("Error");
}
BufferedImage createResizedCopy(Image originalImage, int scaledWidth, int scaledHeight, boolean preserveAlpha) {
int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
Graphics2D g = scaledBI.createGraphics();
if (preserveAlpha) {
g.setComposite(AlphaComposite.Src);
}
g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
g.dispose();
return scaledBI;
}
And I did not use the other code.
Hope helps someone!

write multiple images to outputStream in a servlet

I am reading two images in a servlet and need to show both at the same time.
Currently, only one image is shown (one that is written first). unable to write another image.
I do not get any error.
My servlet code goes like this :
BufferedImage buffImageA = ImageIO.read(getServletContext().getResourceAsStream("/images/3520276097315A.jpg"));
BufferedImage buffImageB = ImageIO.read(getServletContext().getResourceAsStream("/images/3520276097315B.jpg"));
logger.logDebug("Images has been read");
watermark(buffImageA,ApplicationConfig.WATERMARK_TEXT);
watermark(buffImageB,ApplicationConfig.WATERMARK_TEXT);
byte[] resultDataA = encodeJPEG(buffImageA, 100);
byte[] resultDataB = encodeJPEG(buffImageB, 100);
byte[] combinedImage = new byte[resultDataA.length+resultDataB.length];
for(int i=0; i<resultDataA.length ;i++){
combinedImage[i] = resultDataA[i];
}
for(int i=resultDataA.length; i<resultDataB.length ;i++){
combinedImage[i] = resultDataB[i];
}
response.setContentType("image/jpeg");
response.setContentLength(resultDataA.length + resultDataB.length);
OutputStream os = response.getOutputStream();
os.write(combinedImage);
os.close();
//Watermarking process goes here
private void watermark(BufferedImage original, String watermarkText) {
}
private byte[] encodeJPEG(BufferedImage image, int quality) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream((int) ((float) image.getWidth() * image.getHeight() / 4));
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos);
JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
quality = Math.max(0, Math.min(quality, 100));
param.setQuality((float) quality / 100.0f, false);
encoder.setJPEGEncodeParam(param);
encoder.encode(image);
byte[] result = baos.toByteArray();
baos.close();
return result;
}
I have tried using ImageIO.write to write the image but failed to get what is desired.
Your second for loop must be like this:
for(int i=resultDataA.length; i<resultDataB.length+resultDataA.length ;i++){
combinedImage[i] = resultDataB[i-resultDataA.length];
}
EDIT :
This is a compilable, runnable example close to what you're expecting :
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import java.awt.Graphics;
public class Essai2 {
public static void main(String[] args) {
try {
byte[] imageInByte;
BufferedImage originalImage1 = ImageIO.read(new File("essai1.jpg"));
BufferedImage originalImage2 = ImageIO.read(new File("essai2.jpg"));
// convert BufferedImage to byte array
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
ImageIO.write(originalImage1, "jpg", baos1);
ImageIO.write(originalImage2, "jpg", baos2);
baos1.flush();
baos2.flush();
byte[] ba1 = baos1.toByteArray();
byte[] ba2 = baos2.toByteArray();
imageInByte = new byte[ba1.length + ba2.length];
//System.out.println(new String(imageInByte));
System.arraycopy(ba1, 0, imageInByte, 0, ba1.length);
//System.out.println(new String(imageInByte));
System.arraycopy(ba2, 0, imageInByte, ba1.length, ba2.length);
//System.out.println(new String(imageInByte));
baos1.close();
baos2.close();
// convert byte array back to BufferedImage
InputStream in = new ByteArrayInputStream(imageInByte);
int w = Math.max(originalImage1.getWidth(), originalImage2.getWidth());
//int h = Math.max(originalImage1.getHeight(), originalImage2.getHeight());
int h = originalImage1.getHeight() + originalImage2.getHeight();
BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
//BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR );
//BufferedImage bImageFromConvert = ImageIO.read(in);
Graphics g = bImageFromConvert.getGraphics();
g.drawImage(originalImage1, 0, 0, null);
g.drawImage(originalImage2, 0, originalImage1.getHeight(), null);
ImageIO.write(bImageFromConvert, "jpg", new File("result.jpg"));
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}
essai1.jpg:
essai2.jpg:
result.jpg:
I haven't found for the moment why there's a third color added to result.jpg. But I think this example can help you and I will fix my code asap.
EDIT2 :
Change :
BufferedImage bImageFromConvert = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
To :
BufferedImage bImageFromConvert = new BufferedImage(w, h, originalImage1.getType());
And it will works fine.
result.jpg:

How to write an image on disk from blob?

I am tring to create an image file from database on disk. I wrote the following code:
{
oracle.sql.BLOB blob1 = (BLOB) rs.getBlob(1);
//fillFilePath is file path
File blobFile = new File(fillFilePath);
String checkExe[]=fillFilePath.split("\\.");
FileOutputStream outStream = new FileOutputStream(blobFile);
InputStream inStream = blob1.getBinaryStream();
int length = -1;
int size = blob1.getBufferSize();
byte[] buffer = new byte[size];
BufferedImage image = ImageIO.read( inStream );
System.out.println("Inside image upload");
System.out.println("Inside image jpg");
ImageIO.write(image, "JPG", outStream);
But it is not working.
Please give me any suggestions?
try:
BLOB image = ((OracleResultSet) rs).getBLOB("image");
blobLength = image.length();
chunkSize = image.getChunkSize();
binaryBuffer = new byte[chunkSize];
for (position = 1; position <= blobLength; position += chunkSize)
{
bytesRead = image.getBytes(position, chunkSize, binaryBuffer);
outputFileOutputStream.write(binaryBuffer, 0, bytesRead);
totbytesRead += bytesRead;
totbytesWritten += bytesRead;
}
BufferedImage bi= ImageIO.read(obj.getPhoto().getBinaryStream());//photo is Blob.
File outputfile = new File("folderInYourProject\\"+nameVar+".jpg");
ImageIO.write(bi, "jpg", outputfile);

Categories