Rohit Bajaj
asked on
Convert an Image Object in java to byte array
Hi,
I have the following code :
Here I am using ByteArrayOutputStream to convert and Image object to byte array and then to string.
And then SFTP that string data. Although the data is geting stfp'd and i do see a file there.
But when i download the file locally and open it - it gives an error corrupted file.
It looks like probably ByteArrayOutPutStream is not a correct way to convert an Image object.
How do I convert it ?
Thanks
I have the following code :
String imageUrl1 = "https://zeta-s3-bucket-temporary-staging.s3.amazonaws.com/fe6e3c46-3098-4135-be73-eae0b9fff837";
BufferedImage mergedImage = ImageUtils.mergeImages(imageUrl1, imageUrl1);
String type = Doc.DocType.KYC_FORM.toString();
DocUploadEntry docUploadEntry = new DocUploadEntry().applicationId(1564).ifi(140793L).type(Doc.DocType.KYC_FORM).fileName("8178717991_POA.jpg");
SftpCommandService sftpCommandService = new SftpCommandService(20);
String filePath = getFilePath(docUploadEntry);
ChannelSftp channelSftp = getChannel().toCompletableFuture().join();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String data = null;
try {
ImageIO.write(mergedImage, "jpg", byteArrayOutputStream);
byteArrayOutputStream.flush();
data = new String(byteArrayOutputStream.toByteArray());
byteArrayOutputStream.close();
} catch (IOException e) {
}
sftpCommandService.uploadFile(data, filePath, channelSftp).toCompletableFuture().join();
Here I am using ByteArrayOutputStream to convert and Image object to byte array and then to string.
And then SFTP that string data. Although the data is geting stfp'd and i do see a file there.
But when i download the file locally and open it - it gives an error corrupted file.
It looks like probably ByteArrayOutPutStream is not a correct way to convert an Image object.
How do I convert it ?
Thanks
ASKER
Hi,
The SftpCommandService is an internal library.
which has a function :
So i was using this. But now i am stuck.
In the code that i posted I am indeed writing the ByteArrayOutputStream and converting it to String and then sending the data..
But thats not working as i mentioned but the file indeed gets posted...
What do you suggest here ?
should i be using some other library for sftp that can directly sftp the Image java object ?
Thanks
The SftpCommandService is an internal library.
which has a function :
public CompletionStage<Void> uploadFile(String data, String destFilePath, ChannelSftp channelSftp) {
CompletableFuture<Void> uploadFileFuture = new CompletableFuture();
this.executor.execute(() -> {
try {
this.logger.info("Uploading {}", destFilePath);
channelSftp.put(new ByteArrayInputStream(data.getBytes(StandardCharsets.ISO_8859_1)), destFilePath);
uploadFileFuture.complete((Object)null);
} catch (Exception var6) {
uploadFileFuture.completeExceptionally(var6);
}
});
return uploadFileFuture;
}
I found some places that this function is getting used to transfer an image sftp location.So i was using this. But now i am stuck.
In the code that i posted I am indeed writing the ByteArrayOutputStream and converting it to String and then sending the data..
But thats not working as i mentioned but the file indeed gets posted...
What do you suggest here ?
should i be using some other library for sftp that can directly sftp the Image java object ?
Thanks
The SftpCommandService is an internal library.That's not well designed. It should have overridden that method, e.g. to provide a stream as the first parameter. Why assume the file is always a text file?
which has a function :
Are you sure it isn't overridden?
ASKER
I just checked the latest version of the library and found the following code :
public CompletionStage<Void> uploadFile(String data, String destFilePath, ChannelSftp channelSftp) {
return this.uploadFile((InputStream)(new ByteArrayInputStream(data.getBytes(StandardCharsets.ISO_8859_1))), destFilePath, channelSftp);
}
public CompletionStage<Void> uploadFile(InputStream inputStream, String destFilePath, ChannelSftp channelSftp) {
CompletableFuture<Void> uploadFileFuture = new CompletableFuture();
this.executor.execute(() -> {
try {
this.logger.info("Uploading {}", destFilePath);
channelSftp.put(inputStream, destFilePath);
uploadFileFuture.complete((Object)null);
} catch (Exception var14) {
uploadFileFuture.completeExceptionally(var14);
} finally {
try {
inputStream.close();
} catch (IOException var13) {
this.logger.error("Error occurred while closing input stream {}", var13);
}
}
});
return uploadFileFuture;
}
Strangely to me its an InputStream now
Yes, that's better although i can see why you might not think so. Out of interest, what library is 'channelSftp' from?
ASKER
Cool it worked. Thanks for pointing out the design is out of place. I somehow always miss that the library i am using might be old. and i ended up wasting so much time.
I tried this and it worked now :
channelSftp is from com.jcraft:jsch:0.1.54
I tried this and it worked now :
String imageUrl1 = "https://zeta-s3-bucket-temporary-staging.s3.amazonaws.com/fe6e3c46-3098-4135-be73-eae0b9fff837";
BufferedImage mergedImage = ImageUtils.mergeImages(imageUrl1, imageUrl1);
String type = Doc.DocType.KYC_FORM.toString();
DocUploadEntry docUploadEntry = new DocUploadEntry().applicationId(1564).ifi(140793L).type(Doc.DocType.KYC_FORM).fileName("8178717991_POA.jpg");
SftpCommandService sftpCommandService = new SftpCommandService(20);
String filePath = getFilePath(docUploadEntry);
ChannelSftp channelSftp = getChannel().toCompletableFuture().join();
String data = null;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
try {
ImageIO.write(mergedImage, "jpg", byteArrayOutputStream);
byteArrayOutputStream.flush();
} catch (IOException e) {
}
InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
sftpCommandService.uploadFile(inputStream, filePath, channelSftp).toCompletableFuture().join();
channelSftp is from com.jcraft:jsch:0.1.54
Thanks for pointing out the design is out of place.Well not necessarily as it has an override like i mentioned.
Your solution will work but is less than optimal as it will fill memory up to at least the size of the image. It would be better to use a PipedOutStream probably
ASKER
any good articles on explaining the difference between using bytearrayoutputstream and pipedoutputstream. ?
I want to dig somewhat deeper and take this opportunity to understand this input output stream business.
I want to dig somewhat deeper and take this opportunity to understand this input output stream business.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
:)
You should be writing that Image as directly as possible to the sftp stream. Not knowing which library SftpCommandService belongs to, i can't be more specific.
At the very least, write the BAOS to sftp