I am trying to download an image from the internet and save it to my internal storage to be used elsewhere in my app. However the image that is received fails to compress and save. bitmap.compress(Bitmap.CompressFormat.JPEG, 70, out); throws a nullpointer. Any help is appreciated.
private String SaveImage(String imageURL) {
Bitmap bitmap = null;
try {
// Download Image from URL
URL testUrl = new URL(imageURL);
URLConnection urlConnection = testUrl.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
InputStream is = httpURLConnection.getInputStream();
// Decode Bitmap
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
Boolean scaleByHeight = Math.abs(options.outHeight - 300) >= Math.abs(options.outWidth - 300);
if(options.outHeight * options.outWidth * 2 >= 200*200*2){
// Load, scaling to smallest power of 2 that'll get it <= desired dimensions
double sampleSize = scaleByHeight
? options.outHeight / 300
: options.outWidth / 300;
options.inSampleSize =
(int)Math.pow(2d, Math.floor(
Math.log(sampleSize)/Math.log(2d)));
}
// Do the actual decoding
options.inJustDecodeBounds = false;
is.close();
is = httpURLConnection.getInputStream();
bitmap = BitmapFactory.decodeStream(is, null, options);
is.close();
String root = getApplicationContext().getFilesDir().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 100000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".png";
File file = new File(myDir, fname);
if (file.exists()) file.delete();
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 70, out); //here
out.flush();
out.close();
return getApplicationContext().getFilesDir().toString() + "/saved_images/" + "Image-" + n + ".png";
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Related
I want to make android app to merge multiple image from single folder into single pdf file.
ex :
folder name :
- images
- 1.jpg
- 2.jpg
- 3.jpg
- 4.jpg
- 5.jpg
there are 5 images are in folder named images
how can i make pdf of that images?
if anyone have possible solution then please comment answer :)
Try this after 4.4 version it will work.
private void createPDF() {
final File file = new File(uploadFolder, "AnswerSheet_" + queId + ".pdf");
final ProgressDialog dialog = ProgressDialog.show(this, "", "Generating PDF...");
dialog.show();
new Thread(() -> {
Bitmap bitmap;
PdfDocument document = new PdfDocument();
// int height = 842;
//int width = 595;
int height = 1010;
int width = 714;
int reqH, reqW;
reqW = width;
for (int i = 0; i < array.size(); i++) {
// bitmap = BitmapFactory.decodeFile(array.get(i));
bitmap = Utility.getCompressedBitmap(array.get(i), height, width);
reqH = width * bitmap.getHeight() / bitmap.getWidth();
Log.e("reqH", "=" + reqH);
if (reqH < height) {
// bitmap = Bitmap.createScaledBitmap(bitmap, reqW, reqH, true);
} else {
reqH = height;
reqW = height * bitmap.getWidth() / bitmap.getHeight();
Log.e("reqW", "=" + reqW);
// bitmap = Bitmap.createScaledBitmap(bitmap, reqW, reqH, true);
}
// Compress image by decreasing quality
// ByteArrayOutputStream out = new ByteArrayOutputStream();
// bitmap.compress(Bitmap.CompressFormat.WEBP, 50, out);
// bitmap = BitmapFactory.decodeStream(new ByteArrayInputStream(out.toByteArray()));
//bitmap = bitmap.copy(Bitmap.Config.RGB_565, false);
//Create an A4 sized page 595 x 842 in Postscript points.
//PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(595, 842, 1).create();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(reqW, reqH, 1).create();
PdfDocument.Page page = document.startPage(pageInfo);
Canvas canvas = page.getCanvas();
Log.e("PDF", "pdf = " + bitmap.getWidth() + "x" + bitmap.getHeight());
canvas.drawBitmap(bitmap, 0, 0, null);
document.finishPage(page);
}
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
document.writeTo(fos);
document.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
runOnUiThread(() -> {
dismissDialog(dialog);
});
}).start();
}
If you want to create a pdf file with multiple images you can use PdfDocument from Android. Here is a demo:
private void createPDFWithMultipleImage(){
File file = getOutputFile();
if (file != null){
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
PdfDocument pdfDocument = new PdfDocument();
for (int i = 0; i < images.size(); i++){
Bitmap bitmap = BitmapFactory.decodeFile(images.get(i).getPath());
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(bitmap.getWidth(), bitmap.getHeight(), (i + 1)).create();
PdfDocument.Page page = pdfDocument.startPage(pageInfo);
Canvas canvas = page.getCanvas();
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canvas.drawPaint(paint);
canvas.drawBitmap(bitmap, 0f, 0f, null);
pdfDocument.finishPage(page);
bitmap.recycle();
}
pdfDocument.writeTo(fileOutputStream);
pdfDocument.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private File getOutputFile(){
File root = new File(this.getExternalFilesDir(null),"My PDF Folder");
boolean isFolderCreated = true;
if (!root.exists()){
isFolderCreated = root.mkdir();
}
if (isFolderCreated) {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageFileName = "PDF_" + timeStamp;
return new File(root, imageFileName + ".pdf");
}
else {
Toast.makeText(this, "Folder is not created", Toast.LENGTH_SHORT).show();
return null;
}
}
Here images is the ArrayList of the images with path.
Break your problem down into smaller problems. It's a fairly simple application.
Get the folder name from the user. See the native file open dialog to find a folder. See here.
Search its files for images
Create a pdf of the images. Use a library such as apache pdfbox.
Use this iText library
Create a document
String FILE = "{folder-path}/FirstPdf.pdf";
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(FILE));
document.open();
Add image in the document
try {
// get input stream
String fileName = "OfflineMap/abc.jpg";
String path =
Environment.getExternalStorageDirectory()+"/"+fileName;
File file = new File(path);
FileInputStream fileInputStream = new FileInputStream(file);
InputStream ims = getAssets().open("myImage.png");
Bitmap bmp = BitmapFactory.decodeStream(ims);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
Image image = Image.getInstance(stream.toByteArray());
document.add(image);
document.close();
}
catch(IOException ex)
{
return;
}
I want to try download a file from resume in android studio, i have try my code with open stream and don't have any problem but in this code:
public void startStream2(Context context) {
try {
URL url = new URL(file.getFileUrl());
StrictMode.ThreadPolicy ploicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(ploicy);
URLConnection connection = url.openConnection();
int downloaded = 0;
BufferedOutputStream bout;
f = new File(downloadPath, file.getName());
if (f.exists()) {
downloaded = (int) f.length();
connection.setRequestProperty("Range", "bytes=" + (f.length()) + "-");
}
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept","*/*");
connection.connect();
int response=((HttpURLConnection)connection).getResponseCode();
Log.e(TAG, "startStream2: "+ response );
if (response>399 && response<601){
InputStreamReader sr;
sr = new InputStreamReader(((HttpURLConnection) connection).getErrorStream(), "UTF-8");
StringBuilder builder = new StringBuilder();
for (int bt = 0; (bt = sr.read()) != -1;) {
builder.append((char)bt);
}
sr.close();
Log.e(TAG, "startStream2: "+builder.toString());
}
InputStream inp=connection.getInputStream();
BufferedInputStream in = new BufferedInputStream(inp);
stream2 = (downloaded == 0) ? new FileOutputStream(f) : new FileOutputStream(f, true);
bout = new BufferedOutputStream(stream2, 1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data, 0, 1024)) >= 0) {
bout.write(data, 0, x);
downloaded += x;
int percent = ((int) downloaded * 100) / (int) Size;
//set percent progress
}
}catch (Exception e){
Log.e(TAG, "startStream2: ",e );
}
}
Error log:
startStream2: 405 startStream2:
405 Not Allowed
405 Not Allowed
nginx
startStream2:
java.io.FileNotFoundException:
at
com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:242)
I have test the url before and don't have any problem with download from first or resume.
How can i resolve it?
thanks.
connection.setDoOutput(true);
The problem is here. It changes the HTTP verb from GET to POST. You don't want to POST. You aren't sending any output. Remove it.
And if the response code isn't 200 you should not get the input stream, otherwise it will throw an exception. You can get the error stream if you want more info, but there isn't an input stream at this point.
You can also remove
connection.connect();
and
connection.setDoInput(true);
They don't do anything that doesn't already happen.
remove these lines
connection.setDoInput(true);
connection.setDoOutput(true);
Finally i have resolved it by this code:
public void startStream2(Context context) {
try {
URL url = new URL(file.getFileUrl());
StrictMode.ThreadPolicy ploicy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(ploicy);
URLConnection connection = url.openConnection();
int downloaded = 0;
BufferedOutputStream bout;
f = new File(downloadPath, file.getName());
if (f.exists()) {
downloaded = (int) f.length();
connection.setRequestProperty("Range", "bytes=" + (f.length()) + "-");
}
connection.setDoInput(true);
connection.setRequestProperty("User-Agent","Mozilla/5.0 ( compatible ) ");
connection.setRequestProperty("Accept","*/*");
int response=((HttpURLConnection)connection).getResponseCode();
Log.e(TAG, "startStream2: "+ response );
if (response>399 && response<601){
InputStreamReader sr;
sr = new InputStreamReader(((HttpURLConnection) connection).getErrorStream(), "UTF-8");
StringBuilder builder = new StringBuilder();
for (int bt = 0; (bt = sr.read()) != -1;) {
builder.append((char)bt);
}
sr.close();
Log.e(TAG, "startStream2: "+builder.toString());
}
InputStream inp=connection.getInputStream();
BufferedInputStream in = new BufferedInputStream(inp);
stream2 = (downloaded == 0) ? new FileOutputStream(f) : new FileOutputStream(f, true);
bout = new BufferedOutputStream(stream2, 1024);
byte[] data = new byte[1024];
int x = 0;
while ((x = in.read(data, 0, 1024)) >= 0) {
bout.write(data, 0, x);
downloaded += x;
int percent = ((int) downloaded * 100) / (int) Size;
//set percent progress
}
}catch (Exception e){
Log.e(TAG, "startStream2: ",e );
}
}
Thank a lot!
I am downloading a PDF from a URL and saving it to my local drive.
The download code is working perfectly, the problem is that when I try to measure the size of the file it always claims it to be 52 bytes. I'm baffled... could you please review my code and tell me if I'am missing something?
try {
link = new URL("http://www.annualreports.co.uk/HostedData/AnnualReports/PDF/LSE_" + entry[0] + "_2015.pdf");
// http://www.annualreports.co.uk/HostedData/AnnualReports/PDF/LSE_BT_2015.pdf
InputStream in = new BufferedInputStream(link.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while (-1!=(n=in.read(buf)))
{
out.write(buf, 0, n);
}
out.close();
in.close();
byte[] response = out.toByteArray();
FileOutputStream fos = new FileOutputStream(fileName);
fos.write(response);
fos.close();
} catch (Exception e) {
System.out.println("Couldn't retrieve : " + entry[1] + " " + year);
}
int bytes = fileName.length();
System.out.println(bytes);
Here. Just simply try this.
URL url = new URL("http://www.annualreports.co.uk/HostedData/AnnualReports/PDF/LSE_" + entry[0] + "_2015.pdf");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.addRequestProperty("User-Agent", "Mozilla/4.76");
int size = conn.getContentLength();
if (size < 0) {
System.out.println("File not found");
} else {
System.out.println("File size in Bytes: " + size);
}
I using java code for compressing images. Sometimes i am getting image with wrong colors. I don't understand why it's beheviour is inconsistent.
Images downloading from urls
public void imageDownload() {
String key = (String) map.get("key");
String url = (String) map.get("url");
**String imagePath = java.util.UUID.randomUUID() + ".jpg";
String compressedImage = Constant.COMPRESSED + imagePath;**
try {
URL url = new URL(url);
InputStream is = url.openStream();
// Stream to the destionation file
FileOutputStream fos = new FileOutputStream(imagePath);
// Read bytes from URL to the local file
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = is.read(buffer)) != -1)
fos.write(buffer, 0, bytesRead);
// Close destination stream
fos.close();
// Close URL stream
is.close();
compressFile(imagePath, compressedImage, key);
} catch (Exception exception) {
log.debug("Exception occured while downloading images..." + exception.getLocalizedMessage());
}
}
}
Image compression code
private void compressFile(final String inputFilePath, final String outputFilePath,final String fileKey) {
log.debug("Image file name::" + outputFilePath);
log.debug("Image key is::" + fileKey);
final String outputImagePath = tempFilePath + outputFilePath;
final File inputFile = new File(inputFilePath);
float quality = FileUpload.getQuality(inputFile);
log.debug("Image size for url is::" + inputFile.length() + "quality constent::" + quality);
final File outputFile = new File(outputImagePath);
boolean s3Uploaded = true;
if (quality != 0.0f) {
final boolean isCompressed = FileUpload.fileCompress(inputFile, outputFile, quality);
}
}
Compression code
public static boolean fileCompress(File inputFilePath, File outputFilePath, float quality) {
log.debug("File compress with path::" + inputFilePath + "output file path" + outputFilePath);
boolean isCompressed = false;
OutputStream os = null;
ImageOutputStream ios = null;
ImageWriter writer = null;
try {
BufferedImage image = ImageIO.read(inputFilePath);
os = new FileOutputStream(outputFilePath);
Iterator<ImageWriter> writers = ImageIO.getImageWritersByFormatName("jpg");
writer = (ImageWriter) writers.next();
ios = ImageIO.createImageOutputStream(os);
writer.setOutput(ios);
ImageWriteParam param = writer.getDefaultWriteParam();
param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
param.setCompressionQuality(quality);
writer.write(null, new IIOImage(image, null, null), param);
os.close();
ios.close();
writer.dispose();
isCompressed = true;
} catch (Exception exception) {
log.error("File could not compress due to " + exception.getCause());
isCompressed= false;
}
return isCompressed;
}
getting quality parameter
public static float getQuality(File input) {
long size = input.length();
log.debug("getting quality constant on the basis of image size: " + size);
if (size > 768000) {
return 0.3f;
}
if (size > 512000 && size <= 768000) {
return 0.6f;
}
if (size > 256000 && size <= 512000) {
return 0.7f;
}
if (size > 51200) {
return 0.9f;
}
return 0.0f;
}
Destroyed image(image size was before compressing - 84616)
Thanks
I am fetching images from Facebook and writing them to SD card, but the image quality is very low. Following is my code to fetch and write:
try
{
URL url = new URL(murl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
data1 = String.valueOf(String.format(getActivity().getApplicationContext().getFilesDir()+"/Rem/%d.jpg",System.currentTimeMillis()));
FileOutputStream stream = new FileOutputStream(data1);
ByteArrayOutputStream outstream = new ByteArrayOutputStream();
myBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outstream);
byte[] byteArray = outstream.toByteArray();
stream.write(byteArray);
stream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
The following code I use to display the same image:
File IMG_FILE = new File(IMAGE_CONTENT);
B2.setVisibility(View.INVISIBLE);
Options options = new BitmapFactory.Options();
options.inScaled = false;
options.inDither = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(IMG_FILE.getAbsolutePath(),options);
iM.setImageBitmap(bitmap);
The quality is still low even after using Options. What can be done to improve this?
to Save image from URL onto SD card use this code
try
{
URL url = new URL("Enter the URL to be downloaded");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
File SDCardRoot = Environment.getExternalStorageDirectory().getAbsoluteFile();
String filename="downloadedFile.png";
Log.i("Local filename:",""+filename);
File file = new File(SDCardRoot,filename);
if(file.createNewFile())
{
file.createNewFile();
}
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
int totalSize = urlConnection.getContentLength();
int downloadedSize = 0;
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ( (bufferLength = inputStream.read(buffer)) > 0 )
{
fileOutput.write(buffer, 0, bufferLength);
downloadedSize += bufferLength;
Log.i("Progress:","downloadedSize:"+downloadedSize+"totalSize:"+ totalSize) ;
}
fileOutput.close();
if(downloadedSize==totalSize) filepath=file.getPath();
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
filepath=null;
e.printStackTrace();
}
Log.i("filepath:"," "+filepath) ;
return filepath;
use this code to set sdcard image as your imageview bg
File f = new File("/mnt/sdcard/photo.jpg");
ImageView imgView = (ImageView)findViewById(R.id.imageView);
Bitmap bmp = BitmapFactory.decodeFile(f.getAbsolutePath());
imgView.setImageBitmap(bmp);
else use this
File file = ....
Uri uri = Uri.fromFile(file);
imgView.setImageURI(uri);
You can directly show image from web without downloading it. Please check the below function . It will show the images from the web into your image view.
public static Drawable LoadImageFromWebOperations(String url) {
try {
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
return d;
} catch (Exception e) {
return null;
}
}
then set image to imageview using code in your activity.
The issue is that you're dealing with a lossy format (JPG) and are re-compressing the image. Even with quality at 100 you still get loss - you just get the least amount.
Rather than decompressing to a Bitmap then re-compressing when you write it to the file, you want to download the raw bytes directly to a file.
...
InputStream is = connection.getInputStream();
OutputStream os = new FileOutputStream(data1);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
...