Hey Gwener's, What's Up!
Berkaitan dengan artikel sebelumnya berbicara tentang texture, Draw TextureRegion with LibGDX tentunya sobat mungkin masih memiliki kendala ketika ingin mendapatkan image dari url. Pada contoh artikel sebelumnya saya memberikan image yang diload dari file internal project saja.
Pada dasarnya tetap menggunakan InputStream yang diarahkan ke url yang ingin kita tuju. Untuk mendapatkan ini maka kita memerlukan konektifitas internet. untuk itu kita bisa menggunakan org.apache.http.impl.client.DefaultHttpClient, class ini secara otomatis mendeteksi koneksi http yang disupport oleh perangkat atau emulator yang digunakan.
Image from url

Deklarasi InputStream

Sebagai contoh kita mendeklarasikan sebuah input stream menggunakan HttpClient ini. seperti contoh berikut ini.
        String url = "http://URL_YOUR_IMAGE";
 DefaultHttpClient client = new DefaultHttpClient();
 HttpGet request = new HttpGet(url);
 HttpResponse response = client.execute(request);
 HttpEntity entity = response.getEntity();
 int imageLength = (int)(entity.getContentLength());
 InputStream is = entity.getContent();
Selanjutnya adalah mendapatkan Byte[] array dari input stream ini. Cara ini sangat sederhana seperhalnya membaca stream pada umumunya. Kita cukup melakukan loop untuk membaca input stream tersebut.
 byte[] imageBlob = new byte[imageLength];
 int bytesRead = 0;
 while (bytesRead < imageLength) {
  int n = is.read(imageBlob, bytesRead, imageLength - bytesRead);
  if (n <= 0)
   ; // do some error handling
  bytesRead += n;
 }
Byte[] Array inilah yang kita gunakan untuk membentuk Texture ini. Namun untuk membentuk Texture ini kita membutuhkan Pixmap. Sehingga array tersebut bisa dikonversi.

Texture from Pixmap

Untuk melakukan konversi sobat bisa melakukan dengan cara berikut.
 Pixmap pixmap = new Pixmap(textureBytes, 0, textureBytes.length);
 Texture gdxTexture = new Texture(pixmap);
 gdxTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
 pixmap.dispose();
Byte[] Array yang didapat sebelumnya digunakan pada Pixmap tersebut sehingga bisa digunakan sebagai parameter untuk membentuk Texture ini.

Final Class Texture from Url

Seletah menelaah 3 cara diatas maka sebenernarnya kita sudah bisa membuat Texture dari url. Untuk lebih memberikan lokalisasi maka code diatas bisa kita gabungkan dalam sebuah class. Seperti contoh berikut.
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;

public class UrlTexture {
    private final String url;
    private Texture texture;
    private volatile byte[] textureBytes;

    public UrlTexture(String url, Texture tempTexture) {
        this.url = url;
        texture = tempTexture;
        downloadTextureAsync();
    }

    private void downloadTextureAsync() {
        Gdx.app.postRunnable(new Runnable() {
            @Override
            public void run() {
                textureBytes = downloadTextureBytes();
            }
        });
    }

    private byte[] downloadTextureBytes() {
        try {
         
         DefaultHttpClient client = new DefaultHttpClient();
         HttpGet request = new HttpGet(url);
         HttpResponse response = client.execute(request);
         HttpEntity entity = response.getEntity();
         int imageLength = (int)(entity.getContentLength());
         InputStream is = entity.getContent();

         byte[] imageBlob = new byte[imageLength];
         int bytesRead = 0;
         while (bytesRead < imageLength) {
             int n = is.read(imageBlob, bytesRead, imageLength - bytesRead);
             if (n <= 0)
                 ; // do some error handling
             bytesRead += n;
         }
         
            return imageBlob;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public Texture getTexture() {
        if (textureBytes != null)
            processTextureBytes();
        return texture;
    }

    private void processTextureBytes() {
        try {
            Pixmap pixmap = new Pixmap(textureBytes, 0, textureBytes.length);
            Texture gdxTexture = new Texture(pixmap);
            gdxTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
            texture = gdxTexture;
            pixmap.dispose();
        } catch (Throwable t) {
            t.printStackTrace();
        } finally {
            textureBytes = null;
        }
    }
}

2 comments: