I am sending a jpg
image from client. the image is sent in form of blob. Here is the code in javascript which is sending a canvas image
canvas.toBlob((blob) => {
this.setState({preview: blob},
() => {
console.log(blob.size);
let data = new FormData();
// const test = URL.createObjectURL(blob);
// console.log(test);
const file = new File([blob], "File name", {type: "image/png"});
data.append("file", file);
console.log(this.state.preview);
axios({
method: "POST",
data: data,
url: "/media",
headers: {
'Content-Type': 'multipart/form-data'
}
}).then().catch()
// axios.post("http://localhost:8085/api/media", data).then(r => {}).catch()
}
);
}, "image/jpg", 0)
The selected file is a jpg
file which is converted to canvas
for some reasons and then that is sent to the server as blob
.
Here is the server image handling code which is written in java:
public void uploadMedia(MultipartFile mediaFile) {
try{
BufferedImage image = ImageIO.read(mediaFile.getInputStream());
System.out.println(image.getColorModel().getColorSpace().getType() == ColorSpace.TYPE_RGB); //TRUE
ImageIO.write(image, "jpg", new File("/Users/puspender/Desktop/Test/image.jpg")); //BLACK IMAGE with CMYK color space
ImageIO.write(image, "png", new File("/Users/puspender/Desktop/Test/image.png"));
}catch(Exception e){}
}
If I choose png
format for ImageIO.write
the image gets saved successfully fine but if the format is jpg
then a black image gets saved and the color space
of that black image gets changed to CMYK
. Even though it was RGB
with the original file and I have also printed it on console before saving the file.
This issue only comes up when on client the image is cropped(or something) and then a canvas
is created from that and blob
from that canvas
is sent as the payload. No issue comes up when file is selected using <input type="file />
Update: As asked by Mike, I read and re-generated black jpg
which gets generated by ImageIo
. And the result is the same, a black image.
File file = new File("/location/generated_black.jpg");
BufferedImage image = ImageIO.read(file);
ImageIO.write(image, "jpg", new File("/location/from-java-main-400x400.jpg"));
I also tested the above code with the original file and that time ImageIo
handles it correctly.
One important thing I noticed: the black image is actually not black, it is just the disturbed color because of change of color space. I noticed this when I upload this to AWS S3. Here is the image(CMYK
)
The original file below:
I managed to work it correctly. A great personal person on this thread suggested this solution and it even worked well.
But few questions remained the same:
- Why this is only happening with
blob
data sent by javascript and not with normal file selector as mentioned earlier - Why issue only when setting image format to
jpg
and not withpng
? And why change ofcolor space
injpg
byImageIo