I have Facebook graph requests working and seem to have no problem whatsoever, However I have been trying for a while to retrieve the profile picture. But everytime I run it the bitmap seems to turn out null.
public static Bitmap DownloadImageBitmap(String url) {
Bitmap bm = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e("IMAGE", "Error getting bitmap", e);
}
return bm;
}
For Example, If I feed it this string:
String testString = "graph.facebook.com/849993771766163/picture?type=large";
The bitmap will return null every single time..
What am I doing wrong? I suspect I am getting the url wrong but I have tried everything
Try replacing
bm = BitmapFactory.decodeStream(bis);
with
bm = Bitmap.createBitmap(BitmapFactory.decodeStream(bis));
You may also need to create a scaled bitmap first and then set it to your final bitmap before setting it to a view.
Related
Someone is providing a S3 Presigned URL so that I can upload my images to that link. All my images are on the website. Is there a way in JAVA to copy the image URL to the new URL provided ?
I am trying to do this. Seems like an overkill
try {
// Get Image from URL
URL urlGet = new URL("http://something.com/something.png");
BufferedImage image = ImageIO.read(urlGet);
//for png
ImageIO.write(image, "png",new File("/something.png"));
// for jpg
//ImageIO.write(image, "jpg",new File("/something.jpg"));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "png", outputStream);
outputStream.flush();
byte[] imageInBytes = outputStream.toByteArray();
outputStream.close();
URL url = new URL(putUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod(HttpMethod.PUT);
connection.setRequestProperty(HttpHeaders.CONTENT_TYPE, PNG_MIME_TYPE);
OutputStream stream = connection.getOutputStream();
try {
stream.write(imageInBytes);
} finally {
stream.close();
connection.disconnect();
}
switch (connection.getResponseCode()) {
case HttpURLConnection.HTTP_OK:
return "";
default:
break;
}
} catch (Exception e) {
log.error("Exception occured", e);
throw e;
}
There would be no point converting to BufferedImage and back for the copy when you can preserve the byte stream of the original files. The first part can be replaced with simple call to extract the bytes off your website:
byte[] imageInBytes = read(urlGet);
Where read() is:
private static byte[] read(URL url) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream(16*1024);
try (var in = url.openStream()) {
in.transferTo(out);
}
return out.toByteArray();
}
If you use JDK11 onwards you could try the HttpClient class for the GET and POSTs, for example this does same as above if passing it urlGet.toURI():
private static byte[] read(URI uri) throws IOException, InterruptedException
{
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder().uri(uri).build();
var resp = client.send(request, BodyHandlers.ofByteArray());
return resp.body();
}
So, I am downloading the profile picture from the Google SIgn-in api and I save it to a hidden file. The problem is that when I try to retrieve it, it throws me: D/skia: --- Failed to create image decoder with message 'unimplemented'. However when I retrieve an image from FireBaseStorage and save that one to the hidden file I can retrieve it whithout any problems.
I tried BitmapFactory.decodeByteArray(), but then I had a message telling me skia wasn't able to decode the file and it returned null.
The method I use to retrieve the profile picture and call the method that will save the file
private void getUsersPic() {
Bitmap profilePic;
try {
InputStream in = new URL(AppData.getUser().getPicture()).openConnection().getInputStream();
profilePic = BitmapFactory.decodeStream(in);
int size = profilePic.getRowBytes()*profilePic.getHeight();
ByteBuffer b = ByteBuffer.allocate(size);
byte[] bytes = new byte[size];
profilePic.copyPixelsToBuffer(b);
b.position(0);
b.get(bytes, 0, bytes.length);
SaveBitmapToFile.saveBitmap(bytes , AppData.getUser().getName()+AppData.getUser().getLastName());
} catch(Exception e) {
System.out.println("Get profile pic: "+e.toString());
}
}
Save the file
public static void saveBitmap(byte[] bitmap, String key) {
String path = AppData.getAppContext().getFilesDir()+"/.image"+"/";
File fileDir = new File(path);
if(!fileDir.isDirectory())
fileDir.mkdirs();
try {
File bitmapDir = new File(fileDir+"/"+key);
bitmapDir.createNewFile();
FileOutputStream stream = new FileOutputStream(bitmapDir);
stream.write(bitmap);
stream.close();
} catch (IOException e) {
System.out.println("Problem creating file "+e.toString()+ " Directory: "+fileDir);
}
}
Retrieve and return a bitmap
public static Bitmap getBitmap(String key) {
File file = new File(AppData.getAppContext().getFilesDir()+"/.image/"+key);
try {
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(file));
return BitmapFactory.decodeStream(buf);//BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
} catch(Exception e) {
System.out.println("Exception getting bitmap: "+e.toString());
return null;
}
}
The last method should return a Bitmap and it is doing it. It is just not working when the image comes from the Google Sign-in api.
As pskink said in the comment of the post, I had to use compress() instead of copyPixelToBuffer(). Here is my updated method:
private void getUsersPic() {
Bitmap profilePic;
try {
InputStream in = new URL(AppData.getUser().getPicture()).openConnection().getInputStream();
profilePic = BitmapFactory.decodeStream(in);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
profilePic.compress(Bitmap.CompressFormat.PNG, 100, stream);
SaveBitmapToFile.saveBitmap(stream.toByteArray() , AppData.getUser().getName()+AppData.getUser().getLastName());
} catch(Exception e) {
System.out.println("Get profile pic: "+e.toString());
}
}
I'm trying to make a simple function that grabs an image from an http connection. It was working before, now it's throwing some errors. I didn't make any changes to the code. Also the Input stream isn't null. It's returning expected data.
D/skia: ---- read threw an exception
D/skia: --- SkAndroidCodec::NewFromStream returned null
I/ERROR: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.compress(android.graphics.Bitmap$CompressFormat, int, java.io.OutputStream)' on a null object reference
This is my Code for reference inside of an async task:
#Override
protected Bitmap doInBackground(String... url){
try {
InputStream in = openHttpConnection(url[0]);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);
in.close();
return bitmap;
} catch (IOException e) {
Log.i("ERROR", e.toString());
return null;
}
}
private static InputStream openHttpConnection(String urlString) throws IOException {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("Not an HTTP connection");
try {
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
response = httpConn.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpConn.getInputStream();
}
httpConn.disconnect();
} catch (Exception e) {
Log.i("ERROR", e.toString());
throw new IOException("Error connecting");
}
return in;
}
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeStream(in, null, options);
After this statement bitmap is null. It will always be if you ask decodeStream to just decode the bounds.
Later you try to compress that null bitmap with `bitmap.Compress().
It does not matter if that would be in a static function.
Just dont call it if bitmap==null.
I already success display thumbnail video from URL on my android app when internet connection is connected, but when internet connection is off the thumbnail doesn't display.
here is my code.
Bitmap bmThumbnail;
bmThumbnail = ThumbnailUtils.createVideoThumbnail("http://somedomain.com/video/myvideo.mp4", Thumbnails.MICRO_KIND );
imgPhoto.setImageBitmap(bmThumbnail);
i want the thumbnail still display although connection is off,there is away to achieve like save the cache on sdcard first, like image cache does? or any other solution to show thumbnail video when internet connection is off?
thanks,
public static String getBitmapFromURL(final Activity activity, String link,
String filename) throws FileNotFoundException,
MalformedURLException, IOException {
/*--- this method downloads an Image from the given URL,
* then decodes and returns a Bitmap object
---*/
File file = null;
file = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ CommonVariable.KCS_IMAGE_FOLDER_NAME_PHONE_MEMORY);
// have the object build the directory structure, if needed.
if (!file.exists()) {
file.mkdirs();
}
// create a File object for the output file
File outputFile = new File(file, filename);
FileOutputStream fos = new FileOutputStream(outputFile);
BufferedOutputStream out = new BufferedOutputStream(fos, 1024);
URL url = new URL(link);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
out = new BufferedOutputStream(fos, 1024);
int b;
while ((b = input.read()) != -1) {
out.write(b);
}
out.close();
connection.disconnect();
return outputFile.getAbsolutePath();
}
use this function,it will return string of sdcard path.and use this path u can set bitmap image using below function:
public static void setImagesNew(ImageView img, String pathName,
Activity activity) {
Bitmap bmThumbnail = ThumbnailUtils.createVideoThumbnail(pathName, Thumbnails.MICRO_KIND );
img.setImageBitmap(bmThumbnail);
bmp = null;
System.gc();
Runtime.getRuntime().gc();
}
i hope this is useful to you...............
<description>
div class="field field-type-filefield field-field-book-review-image">
<div class="field-items">
<div class="field-item odd">
<img class="imagefield imagefield-field_book_review_image" width="500" height="741" alt="" src="**http://sampada.net/files/good%20earth.JPG?1327387980**" /> &
</description>
You'd better use DOM than SAX. Simply iterate through all elements named "img" , get the "src" attribute, build a URL and fire an AsyncTask to download the stream.
Try the following open source library:
http://htmlcleaner.sourceforge.net/
Following are some more HTML parser:
http://java-source.net/open-source/html-parsers
if you only want 1 pic i would use this:
static final String image_URL = "http://sampada.net/files/good%20earth.JPG?1327387980";
//in the oncreate
ImageView bmImage = (ImageView)findViewById(R.id.<<your image id from the xml>>);
BitmapFactory.Options bmOptions;
bmOptions = new BitmapFactory.Options();
bmOptions.inSampleSize = 1;
Bitmap bm = LoadImage(image_URL, bmOptions);
bmImage.setImageBitmap(bm);
//under the oncreate
private Bitmap LoadImage(String URL, BitmapFactory.Options options)
{
Bitmap bitmap = null;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
bitmap = BitmapFactory.decodeStream(in, null, options);
in.close();
} catch (IOException e1) {
}
return bitmap;
}
private InputStream OpenHttpConnection(String strURL) throws IOException{
InputStream inputStream = null;
URL url = new URL(strURL);
URLConnection conn = url.openConnection();
try{
HttpURLConnection httpConn = (HttpURLConnection)conn;
httpConn.setRequestMethod("GET");
httpConn.connect();
if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
inputStream = httpConn.getInputStream();
}
}
catch (Exception ex)
{
}
return inputStream;
}
hope this helps you.