Created
May 17, 2016 12:06
-
-
Save stefanplindner/ef96abb00204b8e6e0f378cfe026a6d7 to your computer and use it in GitHub Desktop.
PDFRenderer for subsampling-scale-image-view
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Decodes and renders a {@link PdfRenderer.Page} into a {@link Bitmap} | |
* Created by Lindner Stefan on 03.05.16. | |
*/ | |
@SuppressLint("NewApi") | |
public class PDFDecoder implements ImageDecoder { | |
private float scale; | |
/** | |
* the current pdf site | |
*/ | |
private int position; | |
/** | |
* the pdf file to render | |
*/ | |
private File file; | |
/** | |
* basic constructor for PDFDecoder. | |
* @param scale the scale to get from {@link Point} to Pixel | |
*/ | |
public PDFDecoder(int position, File file, float scale) { | |
this.file = file; | |
this.scale = scale; | |
this.position = position; | |
} | |
/** | |
* Creates a {@link Bitmap}in the correct size and renders the {@link PdfRenderer.Page} into it. | |
* @param context not used | |
* @param uri not used | |
* @return a bitmap, containing the pdf page | |
* @throws Exception, if rendering fails | |
*/ | |
@Override public Bitmap decode(Context context, Uri uri) throws Exception { | |
ParcelFileDescriptor descriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);; | |
PdfRenderer renderer = new PdfRenderer(descriptor); | |
final PdfRenderer.Page page = renderer.openPage(position); | |
Bitmap bitmap = Bitmap.createBitmap((int)(page.getWidth()*scale+0.5), (int)(page.getHeight()*scale+0.5f), | |
Bitmap.Config.ARGB_8888); | |
page.render(bitmap,null,null,PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); | |
page.close(); | |
renderer.close(); | |
descriptor.close(); | |
return bitmap; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created by Lindner Stefan on 05.05.2016 | |
*/ | |
@SuppressLint("NewApi") public class PDFPagerAdapter extends PagerAdapter { | |
/** | |
* context for the view | |
*/ | |
private Context context; | |
/** | |
* pdf file to show | |
*/ | |
private File file; | |
/** | |
* file descriptor of the PDF | |
*/ | |
private ParcelFileDescriptor mFileDescriptor; | |
/** | |
* this scale sets the size of the {@link PdfRenderer.Page} in the {@link | |
* PDFRegionDecoder}. | |
* Since it rescales the picture, it also sets the possible zoom level. | |
*/ | |
private float scale; | |
/** | |
* this renderer is only used to count the pages | |
*/ | |
private PdfRenderer renderer; | |
/** | |
* @param file the pdf file | |
*/ | |
public PDFPagerAdapter(Context context, File file) { | |
super(); | |
this.context = context; | |
this.file = file; | |
this.scale = 8; | |
try { | |
mFileDescriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); | |
renderer = new PdfRenderer(mFileDescriptor); | |
} catch (IOException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
/** | |
* Instantiates an item. Therefor a {@link SubsamplingScaleImageView} with special decoders is | |
* initialized and rendered. | |
* | |
* @param container isn't used here | |
* @param position the current pdf page position | |
*/ | |
public Object instantiateItem(ViewGroup container, int position) { | |
SubsamplingScaleImageView imageView = new SubsamplingScaleImageView(context); | |
// the smaller this number, the smaller the chance to get a "outOfMemoryException" | |
// still, values lower than 100 really do affect the quality of the pdf picture | |
int minimumTileDpi = 100; | |
imageView.setMinimumTileDpi(minimumTileDpi); | |
imageView.setBitmapDecoderFactory(() -> new PDFDecoder(position, file, scale)); | |
imageView.setRegionDecoderFactory(() -> new PDFRegionDecoder(position, file, scale)); | |
ImageSource source = ImageSource.uri(file.getAbsolutePath()); | |
imageView.setImage(source); | |
container.addView(imageView); | |
return imageView; | |
} | |
/** | |
* gets the pdf site count | |
* | |
* @return pdf site count | |
*/ | |
public int getCount() { | |
return renderer.getPageCount(); | |
} | |
@Override public void destroyItem(ViewGroup container, int position, Object view) { | |
container.removeView((View) view); | |
} | |
@Override public boolean isViewFromObject(View view, Object object) { | |
return view == object; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Decodes and renders a given rect out of a {@link PdfRenderer.Page} into a {@link Bitmap} | |
* Created by Lindner Stefan on 03.05.16. | |
*/ | |
@SuppressLint("NewApi") public class PDFRegionDecoder implements ImageRegionDecoder { | |
/** | |
* the page that will be rendered to a bitmap. | |
*/ | |
private PdfRenderer renderer; | |
/** | |
* scale: defined in {@link DocumentActivity} | |
*/ | |
private float scale; | |
/** | |
* the current page position in the pdf | |
*/ | |
private int position; | |
/** | |
* the pdf page | |
*/ | |
private PdfRenderer.Page page; | |
/** | |
* the file descriptor | |
*/ | |
private ParcelFileDescriptor descriptor; | |
/** | |
* the pdf file | |
*/ | |
private File file; | |
/** | |
* basic constructor for PDFDecoder. | |
* | |
* @param scale the scale to get from {@link Point} to Pixel | |
*/ | |
public PDFRegionDecoder(int position,File file, float scale) { | |
this.file = file; | |
this.scale = scale; | |
this.position = position; | |
} | |
/** | |
* Initializes the region decoder. This method initializes | |
* @param context not used here | |
* @param uri not used here (file is already loaded) | |
* @return the rescaled point | |
* @throws Exception | |
*/ | |
@Override public Point init(Context context, Uri uri) throws Exception { | |
this.descriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY); | |
this.renderer = new PdfRenderer(descriptor); | |
page = renderer.openPage(position); | |
return new Point((int) ((page.getWidth() * scale + 0.5f)), | |
(int) ((page.getHeight() * scale + 0.5f))); | |
} | |
/** | |
* Creates a {@link Bitmap} in the correct size and renders the region defined by rect of the | |
* {@link PdfRenderer.Page} into it. | |
* | |
* @param rect the rect of the {@link PdfRenderer.Page} to be rendered to the bitmap | |
* @param sampleSize the sample size | |
* @return a bitmap containing the rendered rect of the page | |
*/ | |
@Override public Bitmap decodeRegion(Rect rect, int sampleSize) { | |
int bitmapWidth = rect.width() / sampleSize; | |
int bitmapHeight = rect.height() / sampleSize; | |
Bitmap bitmap = Bitmap.createBitmap(bitmapWidth , bitmapHeight, | |
Bitmap.Config.ARGB_8888); | |
Matrix matrix = new Matrix(); | |
matrix.setScale(scale/sampleSize,scale/sampleSize); | |
matrix.postTranslate(-rect.left/sampleSize, -rect.top/sampleSize); | |
page.render(bitmap, null, matrix, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY); | |
return bitmap; | |
} | |
@Override public boolean isReady() { | |
return true; | |
} | |
/** | |
* close everything | |
*/ | |
@Override public void recycle() { | |
page.close(); | |
renderer.close(); | |
try { | |
descriptor.close(); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To be more generic and close to the original API, I prefer to work with
Uri
instead ofFile
in the renderers.So I replaced this line:
this.descriptor = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
by this line:
this.descriptor = context.contentResolver.openFileDescriptor(uri, "r")