/*
* Copyright (C) 2011 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.panoramio;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Utilities for loading a bitmap from a URL. All network transactions and
* image scaling is done on non-UI thread using AsyncTask.
*/
public class BitmapUtilsTask extends AsyncTask<Object, Void, Bitmap> {
private static final String TAG = "Panoramio";
/**
* Loads a bitmap from the specified url.
*
* @param url The location of the bitmap asset
* @return The bitmap, or null if it could not be loaded
* @throws IOException
* @throws MalformedURLException
*/
public Bitmap getBitmap(final String string, Object fileObj) throws MalformedURLException, IOException {
File file = (File)fileObj;
// Get the source image's dimensions
int desiredWidth = 1000;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
if (!file.isFile()) {
InputStream is = (InputStream) new URL(string).getContent();
BitmapFactory.decodeStream(is, null, options);
is.close();
} else {
BitmapFactory.decodeFile(file.getAbsolutePath(), options);
}
int srcWidth = options.outWidth;
int srcHeight = options.outHeight;
// Only scale if the source is big enough. This code is just trying
// to fit a image into a certain width.
if (desiredWidth > srcWidth)
desiredWidth = srcWidth;
// Calculate the correct inSampleSize/scale value. This helps reduce
// memory use. It should be a power of 2
int inSampleSize = 1;
while (srcWidth / 2 > desiredWidth) {
srcWidth /= 2;
srcHeight /= 2;
inSampleSize *= 2;
}
// Decode with inSampleSize
options.inJustDecodeBounds = false;
options.inDither = false;
options.inSampleSize = inSampleSize;
options.inScaled = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
options.inPurgeable = true;
Bitmap sampledSrcBitmap;
if (!file.isFile()) {
InputStream is = (InputStream) new URL(string).getContent();
sampledSrcBitmap = BitmapFactory.decodeStream(is, null, options);
is.close();
} else {
sampledSrcBitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), options);
}
return sampledSrcBitmap;
}
private void loadBitmap(String url, Object fileObj) {
File file = (File)fileObj;
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet request = new HttpGet(url);
try {
HttpResponse response = client.execute(request);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Header[] headers = response.getHeaders("Location");
if (headers != null && headers.length != 0) {
String newUrl = headers[headers.length - 1].getValue();
// call again with new URL
loadBitmap(newUrl, file);
return;
}
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
FileOutputStream out = new FileOutputStream(file);
try {
inputStream = entity.getContent();
byte buf[] = new byte[16384];
do {
int numread = inputStream.read(buf);
if (numread <= 0)
break;
out.write(buf, 0, numread);
} while (true);
} finally {
if (inputStream != null) {
inputStream.close();
out.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
request.abort();
} finally {
if (client != null) {
client.close();
}
}
}
/**
* Loads a bitmap from the specified url.
*
* @param url The location of the bitmap asset
* @return The bitmap, or null if it could not be loaded
*/
public Bitmap loadThumbnail(String string) {
Bitmap bitmap = null;
InputStream is;
try {
is = (InputStream) new URL(string).getContent();
BitmapFactory.Options optsDownSample = new BitmapFactory.Options();
bitmap = BitmapFactory.decodeStream(is, null, optsDownSample);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
/**
* The system calls this to perform work in a worker thread and delivers
* it the parameters given to AsyncTask.execute()
*/
@Override
protected Bitmap doInBackground(Object... item) {
try {
if (item[1].toString().equals("thumb"))
return loadThumbnail(item[0].toString());
else if (item[1].toString().equals("load")) {
loadBitmap(item[0].toString(), item[2]);
return null;
} else
return getBitmap(item[0].toString(), item[2]);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}