spring-attic / spring-cloud-gcp

Integration for Google Cloud Platform APIs with Spring
Apache License 2.0
704 stars 693 forks source link

java.net.MalformedURLException: unknown protocol: gs #2652

Closed Uvindu96 closed 3 years ago

Uvindu96 commented 3 years ago

Describe the bug

Hi All,

I'm trying to provide the image file path stored in the GCP storage bucket. When I provide the URL I'm getting the following error. I'm parsing the path to Paths.get() method. really appreciate your help..!

localhost_8080_getLabelMLModel_ - Google Chrome 3_5_2021 6_16_15 AM

This is the code sample that I tried,

    @GetMapping("/getLabelMLModel")
    public String getLabelMLModel () throws MalformedURLException {
        GetImage newImage = new GetImage();
        String getImagePath = newImage.getImageUrl();

        String getOutput = "";
        PreProcessor newP = new PreProcessor();

        String modelDir = "src/inception5h";
        String imageFile = "gs://<bucket-name>-images-input/Taj_Mahal.jpeg";

        String getPath = "http://<bucket-name>-images-input.storage.googleapis.com/Taj_Mahal.jpeg";

    byte[] graphDef = newP.readAllBytesOrExit(Paths.get(modelDir, "tensorflow_inception_graph.pb"));
        List<String> labels =
                newP.readAllLinesOrExit(Paths.get(modelDir, "imagenet_comp_graph_label_strings.txt"));
        byte[] imageBytes = newP.readAllBytesOrExit(Paths.get(getPath));

        try (Tensor<Float> image = newP.constructAndExecuteGraphToNormalizeImage(imageBytes)) {
            float[] labelProbabilities = newP.executeInceptionGraph(graphDef, image);
            int bestLabelIdx = newP.maxIndex(labelProbabilities);
            System.out.println(
                    String.format("BEST MATCH: %s (%.2f%% likely)",
                            labels.get(bestLabelIdx),
                            labelProbabilities[bestLabelIdx] * 100f));
            getOutput = String.format("BEST MATCH: %s (%.2f%% likely)",
                    labels.get(bestLabelIdx),
                    labelProbabilities[bestLabelIdx] * 100f);
        }
        return getOutput;
    }
ttomsu commented 3 years ago

Hi @Uvindu96,

This looks similar to an issue I just fixed in our new repo: https://github.com/GoogleCloudPlatform/spring-cloud-gcp/pull/341

It's not clear from your sample code exactly which line is line 82 (from the stacktrace), so I'm not 100% sure it's the same issue.

Regardless, we know a gs://bucket/object URI will not parse into a URL without registering a custom URLStreamHandler, which most users do not have.

Are you trying to get the image bytes, or create a URL and pass it something else that will get the bytes?

meltsufin commented 3 years ago

@Uvindu96 Which URL are you providing? I only see one path with a gs: protocol in your code.

String imageFile = "gs://<bucket-name>-images-input/Taj_Mahal.jpeg";

And I don't see where imageFile is actually used.

Uvindu96 commented 3 years ago

@ttomsu @meltsufin Thanks for the quick response, I made some changes but still the error, this is the code that was trying

@GetMapping("/getLabelMLModelNew")
    public String getLabelMLModelNew (String imageUrl) throws IOException {
        GetImage newImage = new GetImage();
        //String getImagePath = newImage.getImageUrl();

        String getOutput = "";
        PreProcessor newP = new PreProcessor();

        String modelDir = "src/inception5h";
        String imageFile = "gs://stone-semiotics-297911-images-input/Taj_Mahal.jpeg";
        String imageFileExtend = "http://stone-semiotics-297911-images-input.storage.googleapis.com/Taj_Mahal.jpeg";

        UrlValidatorDef newUrl = new UrlValidatorDef(imageFile);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedImage image = ImageIO.read(new URL(newUrl.url));
        ImageIO.write(image, "jpg", baos );
        byte[] getImageBytes = baos.toByteArray();

        byte[] graphDef = newP.readAllBytesOrExit(Paths.get(modelDir, "tensorflow_inception_graph.pb"));
        List<String> labels =
                newP.readAllLinesOrExit(Paths.get(modelDir, "imagenet_comp_graph_label_strings.txt"));
        //byte[] imageBytes = newP.readAllBytesOrExit(Paths.get(imageFile));

        try (Tensor<Float> setImage = newP.constructAndExecuteGraphToNormalizeImage(getImageBytes)) {
            float[] labelProbabilities = newP.executeInceptionGraph(graphDef, setImage);
            int bestLabelIdx = newP.maxIndex(labelProbabilities);
            System.out.println(
                    String.format("BEST MATCH: %s (%.2f%% likely)",
                            labels.get(bestLabelIdx),
                            labelProbabilities[bestLabelIdx] * 100f));
            getOutput = String.format("BEST MATCH: %s (%.2f%% likely)",
                    labels.get(bestLabelIdx),
                    labelProbabilities[bestLabelIdx] * 100f);
        }
        return getOutput;
    }
Uvindu96 commented 3 years ago

@meltsufin If I use the imageFile path I'm getting the unknown protocol error. If it's fixed now, do I have to use a newer version of spring-GCP dependency?

Uvindu96 commented 3 years ago

@ttomsu yes I'm taking the image to a byte stream.

ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedImage image = ImageIO.read(new URL(newUrl.url));
        ImageIO.write(image, "jpg", baos );
        byte[] getImageBytes = baos.toByteArray();
meltsufin commented 3 years ago

@Uvindu96 Try this:

@Autowired
ApplicationContext ctx;
...
String imageFile = "gs://stone-semiotics-297911-images-input/Taj_Mahal.jpeg";
Resource imageFileResource = ctx.getResource(imageFile);
bytes[] imageBytes = StreamUtils.copyToByteArray(imageFileResource.getInputStream());
Uvindu96 commented 3 years ago

This issue is resolved, Thanks to both of you