Loading textures from the internet

Started by Andrew_3ds, December 14, 2016, 23:17:36

Previous topic - Next topic

Andrew_3ds

From what I'm guessing, SeekableByteChannels doesn't load URLs from the Internet. This is what I currently use to load textures from local storage:
public static Texture loadTexture(String location) throws IOException {
        ByteBuffer rawImage = ioResourceToByteBuffer(location);
        IntBuffer w = BufferUtils.createIntBuffer(1);
        IntBuffer h = BufferUtils.createIntBuffer(1);
        IntBuffer d = BufferUtils.createIntBuffer(1);

        ByteBuffer storage = STBImage.stbi_load_from_memory(rawImage, w, h, d, 4);
        if(storage == null) {
            System.out.println(STBImage.stbi_failure_reason());
        }

        MemoryUtil.memFree(rawImage);

        return new Texture().create(w.get(), h.get(), new Texture.Parameters(), storage);
    }

    private static ByteBuffer ioResourceToByteBuffer(String location) throws IOException {
        ByteBuffer buffer = null;

        Path path = Paths.get(location);
        if(Files.isReadable(path)) {
            SeekableByteChannel byteChannel = Files.newByteChannel(path);
            buffer = BufferUtils.createByteBuffer((int) (byteChannel.size()+1));
            while((byteChannel.read(buffer)) != -1);
        }

        return (ByteBuffer)buffer.flip();
    }


How would I get STB to load a texture from memory that I got online? Would I just have to download the image locally and load it?

Kai

Well, if the internet resource is accessible using the HTTP protocol, you can just use any of the vast amounts of available HTTP client frameworks for Java, including the URLConnection class of the JRE, buffer the incoming data into a dynamic byte array, such as a ByteArrayOutputStream, load that into a direct ByteBuffer and use stb to load from memory.

Andrew_3ds

Thanks. I came up with this:

private static ByteBuffer onlineResourceToByteBuffer(URL url) throws IOException {
        URLConnection connection = url.openConnection();
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        InputStream in = connection.getInputStream();
        byte[] chunk = new byte[4096];
        int n;
        while((n = in.read(chunk)) > 0) {
            out.write(chunk, 0, n);
        }
        in.close();
        out.close();
        ByteBuffer buffer = BufferUtils.createByteBuffer(out.size());
        buffer.put(out.toByteArray());

        return (ByteBuffer)buffer.flip();
    }