I have PDF files that contains 1 single icon.
I need to render this icons in GridView.
On Android 5 I'm using PdfRenderer system class and it works amazing:
On Android 4, I'm using "Android-Pdf-Viewer-Library".
https://github.com/jblough/Android-Pdf-Viewer-Library
It works, but the quality is poor:
Can you please suggest any alternatives for rendering PDF as Bitmap?
Or maybe there is a way to increase quality of rendering for that library?
Here is my code:
private static Bitmap renderToBitmap(Context context, InputStream inStream) {
Bitmap bitmap = null;
try {
byte[] decode = IOUtils.toByteArray(inStream);
ByteBuffer buf = ByteBuffer.wrap(decode);
PDFPage mPdfPage = new PDFFile(buf).getPage(0, true);
float width = mPdfPage.getWidth();
float height = mPdfPage.getHeight();
bitmap = mPdfPage.getImage((int) (width), (int) (height), null, true,
true);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
inStream.close();
} catch (IOException e) {
}
}
return bitmap;
}
Related
How to get the bitmap of current layout(For sharing the screen as image) instead of taking screenshot? I'm getting the view of layout using following line,
I can able to get bitmap of this layout but the image is looking as empty(I got blank image). This is my code.
View cardShareView = getLayoutInflater().inflate(R.layout.activity_cad_profile, null);
boolean imageResult=saveImageInLocal(getBitmapFromView(cardShareView), "cad_share.png") == true
public static Bitmap getBitmapFromView(View view) {
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
view.draw(canvas);
return bitmap;
}
private boolean saveImageInLocal(Bitmap imageData, String filename) {
String iconsStoragePath = Environment.getExternalStorageDirectory() + "/KKMC/";
File sdIconStorageDir = new File(iconsStoragePath);
//create storage directories, if they don't exist
sdIconStorageDir.mkdirs();
try {
filePath = sdIconStorageDir.toString() + filename;
FileOutputStream fileOutputStream = new FileOutputStream(filePath);
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
//choose another format if PNG doesn't suit you
imageData.compress(Bitmap.CompressFormat.PNG, 70, bos);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
Log.w("TAG", "Error saving image file: " + e.getMessage());
return false;
} catch (IOException e) {
Log.w("TAG", "Error saving image file: " + e.getMessage());
return false;
}
return true;
}
Advance Thanks for your response.
Expecting this image
Bit I got this image
Finally, I created duplicate layout(activity_cad_profile.xml) for take the full view as image which is loaded at the time of main layout is loading. I don't know this is correct way or not. But it's working fine for me.
I am doing a simple application on Android which is the following:
Putting a QR code Image in the Drawable file of the application. By a ButtonClick, it should be decoded and Display the result (using Zxing library).
I have made the same application on Java (the decoding was then using BufferedImageLuminanceSource class).
In my android application, I used the RGBLuminanceSource class as follows:
LuminanceSource source = new RGBLuminanceSource(width, height, pixels)BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
The problem I am facing here is that: the image has to be too small to be decoded by the android application(and I had to try many sizes to finally got one where the QR code Image is decoded). Meanwhile the same images were decoded easily using the BufferedImageLuminanceSource in Java application without any need to be resized.
What to do to avoid this resizing Problem?
Its too late but it can be help to others,
So we can get Qr code Info from Bitmap using Zxing library.
Bitmap generatedQRCode;
int width = generatedQRCode.getWidth();
int height = generatedQRCode.getHeight();
int[] pixels = new int[width * height];
generatedQRCode.getPixels(pixels, 0, width, 0, 0, width, height);
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
Reader reader = new MultiFormatReader();
Result result = null;
try {
result = reader.decode(binaryBitmap);
} catch (NotFoundException e) {
e.printStackTrace();
} catch (ChecksumException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
}
String text = result.getText();
textViewQRCode.setText(" CONTENT: " + text);
I am writing some text on Image which will be compressed.
Image sie 2048 x 1536 Something px
I first tried to write first
It throws OutOfMemory Exception
then i first compressed it to 1024 x 768
Then Written text on the Image
It increased the Image KB's from 100KB to 640KB
While writing text i can compromise the Image quality but not the text Quality
on Compression quality set to 30 the text also goes downsample
Questions:
is there any process to write then compress or Compress then Write
text without changing the ImageSize(in KB)?
I want Image Size(in KB) as less as Possible?
And also When inSampleSize is set to 3 it does not work and only the image of 2048 , 1024 , 512 using 1 , 2 , 4 is created as output I want image of some size arround 700px maintaining aspect ration.
Codes:.
Method for StampingImage
public void stampMyImage(String filePath, String text, Bitmap bitmap) {
String[] str = text.split("\n");
filePath = "/sdcard/geoTag/1imagelong_001_001_0002_0002_1135_130708144229.jpg";
bitmap = BitmapFactory.decodeFile(filePath);
if (bitmap != null) {
Bitmap dest = null;
try {
dest = bitmap.copy(bitmap.getConfig(), true);
} catch (OutOfMemoryError e1) {
Log.e("Exception", e1.getMessage());
e1.printStackTrace();
} catch (Error e) {
Log.e("Exception", e.getMessage());
e.printStackTrace();
}
Canvas cs = new Canvas(dest);
Typeface tf = Typeface.create("Verdana", Typeface.BOLD);
Paint tPaint = new Paint();
tPaint.setAntiAlias(true);
tPaint.setTextSize(40);
tPaint.setTextAlign(Align.LEFT);
tPaint.setTypeface(tf);
tPaint.setColor(Color.RED);
tPaint.setStyle(Style.FILL_AND_STROKE);
cs.drawBitmap(bitmap, 0f, 0f, null);
float textHeight = tPaint.measureText("yY");
int index = 0;
for (String Oneline : str) {
cs.drawText(Oneline, 20f, (index + 1) * textHeight + 25f,
tPaint);
index++;
}
try {
FileOutputStream fos = new FileOutputStream(
"/sdcard/timeStampedImage.jpg");
dest.compress(Bitmap.CompressFormat.JPEG, 100, fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Method for Regular Compression
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 4;
int quality = 70;
myBitmapClose = BitmapFactory.decodeFile(imgUriClose.getPath(),options);
if (myBitmapClose != null) {
File sdImageMainDirectory = new File(imgUriClose.getPath());
try {
FileOutputStream fileOutputStream = new FileOutputStream(sdImageMainDirectory);
BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
myBitmapClose.compress(CompressFormat.JPEG, quality, bos);
if (bos != null) {
bos.flush();
bos.close();
}
if (fileOutputStream != null) {
fileOutputStream.flush();
fileOutputStream.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Image Sample
See Also
Some useful links i followed
How to write text on an image in Java (Android)
Generate a image with custom text in Android
Drawing Text (TimeStamp) Over image captured from Standalone Camera
Your problem is the allowed allocation memory for your app.
When you load images to bitmap variables (decodeFile or bitmap.copy) try to set the options to decrease image quality. For example, when you do bitmap.copy try to set the options like this:
bitmap.copy(Bitmap.Config.ARGB_4444, true);
I am working with pdf files, I want to implement page viewer to my pdf file. My idea is to convert pdf file into bmp images, and then to use viewPager. but I am stuck in converting pdf to bitmap. Any suggestions?
Include dependencies in your gradle
compile 'com.github.barteksc:android-pdf-viewer:2.8.1'
Use following function to convert PDF page to bitmap image
private Bitmap generateImageFromPdf(String assetFileName, int pageNumber, int width, int height) {
PdfiumCore pdfiumCore = new PdfiumCore(mActivity);
try {
File f = FileUtils.fileFromAsset(mActivity, assetFileName);
ParcelFileDescriptor fd = ParcelFileDescriptor.open(f, ParcelFileDescriptor.MODE_READ_ONLY);
PdfDocument pdfDocument = pdfiumCore.newDocument(fd);
pdfiumCore.openPage(pdfDocument, pageNumber);
//int width = pdfiumCore.getPageWidthPoint(pdfDocument, pageNumber);
//int height = pdfiumCore.getPageHeightPoint(pdfDocument, pageNumber);
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
pdfiumCore.renderPageBitmap(pdfDocument, bmp, pageNumber, 0, 0, width, height);
//saveImage(bmp, filena);
pdfiumCore.closeDocument(pdfDocument);
return bmp;
} catch(Exception e) {
//todo with exception
}
return null;
}
this is a way to render pdf to image
its take 20 to 25 seconds to render pdf file to image
its working in android 10 , android 9 and all lower versions
private void generateImageFromPdf() {
try {
PDDocument doc=PDDocument.load(new File(fileurl));
PDFRenderer pdfRenderer = new PDFRenderer(doc);
Bitmap bffim = pdfRenderer.renderImageWithDPI(0, 100, Bitmap.Config.RGB_565);
String fileName = "image-" + 0 + ".png";
img.setImageBitmap(bffim);
} catch (IOException e) {
e.printStackTrace();
}
}
I would like to load a cropped version of a bitmap image into a Bitmap object, without loading the original bitmap as well.
Is this at all possible without writing custom loading routines to handle the raw data?
Thanks,
Sandor
It's actually very straightforward to do. Use
Bitmap yourBitmap = Bitmap.createBitmap(sourceBitmap, x to start from, y to start from, width, height)
Update: use BitmapRegionDecoder
try this
InputStream istream = null;
try {
istream = this.getContentResolver().openInputStream(yourBitmapUri);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
}
BitmapRegionDecoder decoder = null;
try {
decoder = BitmapRegionDecoder.newInstance(istream, false);
} catch (IOException e) {
e.printStackTrace();
}
Bitmap bMap = decoder.decodeRegion(new Rect(istream, x to start from, y to start from, x to end with, y to end with), null);
imageView.setImageBitmap(bMap);
#RKN
Your method can also throw OutOfMemoryError exception - if cropped bitmap exceeds VM.
My method combines Yours and protection against this exeption:
(l, t, r, b - % of image)
Bitmap cropBitmap(ContentResolver cr, String file, float l, float t, float r, float b)
{
try
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
// First decode with inJustDecodeBounds=true to check dimensions
BitmapFactory.decodeFile(file, options);
int oWidth = options.outWidth;
int oHeight = options.outHeight;
InputStream istream = cr.openInputStream(Uri.fromFile(new File(file)));
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(istream, false);
if (decoder != null)
{
options = new BitmapFactory.Options();
int startingSize = 1;
if ((r - l) * oWidth * (b - t) * oHeight > 2073600)
startingSize = (int) ((r - l) * oWidth * (b - t) * oHeight / 2073600) + 1;
for (options.inSampleSize = startingSize; options.inSampleSize <= 32; options.inSampleSize++)
{
try
{
return decoder.decodeRegion(new Rect((int) (l * oWidth), (int) (t * oHeight), (int) (r * oWidth), (int) (b * oHeight)), options);
}
catch (OutOfMemoryError e)
{
Continue with for loop if OutOfMemoryError occurs
}
}
}
else
return null;
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
and returns max available bitmap or null
Use RapidDecoder.
And simply do this
import rapid.decoder.BitmapDecoder;
Rect bounds = new Rect(left, top, right, bottom);
Bitmap bitmap = BitmapDecoder.from(getResources(), R.drawable.image)
.region(bounds).decode();
It requires Android 2.2 or above.
You can load the scaled version of bitmap with out fully loading the bitmap using following algorithm
Calculate the maximum possible inSampleSize that still yields an
image larger than your target.
Load the image using
BitmapFactory.decodeFile(file, options), passing inSampleSize as an
option.
Resize to the desired dimensions using
Bitmap.createScaledBitmap().
Check the following post
Android: Resize a large bitmap file to scaled output file for further details.