0
votes

I am uploading images to Cloud Storage using the Java Client Library Images are uploaded to Bucket but when I am trying to access them, a Black screen is displaying in browser. So, I dug into this to check the type of the Image after it is uploaded into Cloud Storage.

I uploaded the image I downloaded from the cloud storage to Check File Type .com and it is showing file type as data and MIME/TYPE as application/octet-stream instead of image

enter image description here

So , I uploaded the original image of the same from my PC and it is perfectly showing the image type as image/jpeg

enter image description here

Here is the code I have written using the Java client library.

HTML Form to handle the upload

<form action="/through" method="post" enctype="multipart/form-data">
<h3>Uploading File through App Engine instances to cloud storage</h3>
<label>Enter Your Team Name</label><br>
<input type="text" name="TeamName" ><br><br> 
<label>Upload Team Logo</label><br>
<input type="file" name="teamLogo" required="required"><br><br>
<input type="submit" value="Upload Team Logo">
</form>

Java code to Upload the Image

InputStream input = request.getInputStream();
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
try {
  int read = input.read();
  while(read != -1) {
    byteArrayStream.write(read);
    read = input.read();
  }
catch (IOException e){
  //Handle Exception 
}

byte[] fileBytes = byteArrayStream.toByteArray();

Storage storage = null;
    try {
        FileInputStream credentialsStream = new FileInputStream("JSONFile");
        Credentials credentials = GoogleCredentials.fromStream(credentialsStream);
        storage = StorageOptions.newBuilder().setCredentials(credentials).setProjectId("myProjectID").build().getService();

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    BlobId blobId = BlobId.of(BUCKET_NAME, USER_NAME+"TeamLogo.jpg");
    BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/jpeg").build();
    Blob blob = storage.create(blobInfo, fileBytes);

Why Cloud Storage is not able to detect the type of image properly? It is having adverse effects on other parts of my application where I want to display the same images.

UPDATE

In Console for the same object, Content-Type is showing as image/jpeg

enter image description here

2
In the Google Console -> Storage -> Select Object. Far right click column click on the triple dots -> Edit Metadata. What does the metadata header for Content-Type show for this object? - John Hanley
Hi @JohnHanley , As you suggested I searched for it and had taken a screenshot of the same and added as a update to the answer. It is showing Content-Type as image/jpeg - Abhiram V
The Content-Type matches your java code. Your problem is not with the upload unless the length is wrong. Update your question on how you are accessing these image (the download and display part). - John Hanley
Download the object using the Google Cloud Console. Verify that the downloaded file matches byte for byte what was uploaded. - John Hanley
I think your problem is with ByteArrayOutputStream and the code that builds byteArrayStream. - John Hanley

2 Answers

2
votes

Try this code:

package com.example.storage;

import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;

import java.io.File;
import java.nio.file.Files;
public class QuickstartSample {
  public static void main(String... args) throws Exception {
    File fi = new File("source.jpg");
    Storage storage = StorageOptions.getDefaultInstance().getService();
    BlobId blobId = BlobId.of("your-bucket", "imagen.jpg");
    BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("image/jpeg").build();
    Blob blob = storage.create(blobInfo, Files.readAllBytes(fi.toPath()));
    System.out.println(blob.getContentType());
  }
}

I got the following result on CheckFileType: enter image description here

0
votes

Instead of uploading a file to your local instance, and then moving it to the Cloud Storage, you can instruct your client app to directly upload the file to the Cloud Storage using resumable upload.

If you do need to get file to your local instance first (e.g. for some processing before uploading it), you can use:

ByteArrayOutputStream buffer = new ByteArrayOutputStream();

int nRead;
byte[] data = new byte[16384];

while ((nRead = inStream.read(data, 0, data.length)) != -1) {
  buffer.write(data, 0, nRead);
}

buffer.flush();