Android Studio中用iText5添加PDF图片报NullPointerException的解决方法
解决Android中iText5添加图片时的NullPointerException问题
嘿,我太懂你试了四种方法都碰壁的烦躁了——其实问题核心出在资源路径错误或者Drawable类型不兼容上,我给你捋清楚靠谱的实现方式,分两种常用场景:
先说说你之前尝试的问题
快速拆解下你那四段代码的问题:
- 方法1:
assets.open("res/drawable/logo.png")完全搞错了目录,res/drawable和assets是两个独立的资源文件夹,assets里根本没有这个路径。 - 方法2/3:直接强制把Drawable转成BitmapDrawable,如果你的
logo是矢量图(VectorDrawable),这会直接抛出ClassCastException,进而引发后续的NPE。 - 方法4:
Image.getInstance("res/drawable/logo.png")不认识Android的内部资源路径,iText会把它当成手机文件系统的路径,自然找不到资源。
正确实现方式
方式1:从res/drawable读取(兼容矢量图)
不管你的图片是普通Bitmap还是矢量图,这种方式都能安全转换:
import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import androidx.core.content.ContextCompat; import com.itextpdf.text.BadElementException; import com.itextpdf.text.Image; import java.io.ByteArrayOutputStream; import java.io.IOException; public Image getLogoFromDrawable(Context context) { try { // 用ContextCompat.getDrawable兼容不同Android版本 Drawable drawable = ContextCompat.getDrawable(context, R.drawable.logo); if (drawable == null) { throw new IOException("找不到指定的Drawable资源"); } // 将Drawable转为Bitmap(兼容矢量图) Bitmap bitmap = Bitmap.createBitmap( drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888 ); Canvas canvas = new Canvas(bitmap); drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); drawable.draw(canvas); // 转成iText能识别的Image对象 ByteArrayOutputStream stream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream); Image image = Image.getInstance(stream.toByteArray()); // 可选:调整图片大小,比如缩放至宽100px image.scaleToFit(100, 100); return image; } catch (IOException | BadElementException e) { e.printStackTrace(); return null; } }
方式2:从assets目录读取
如果你把图片放到assets文件夹下(比如创建assets/images/logo.png),可以直接读取:
import android.content.Context; import com.itextpdf.text.BadElementException; import com.itextpdf.text.Image; import java.io.IOException; import java.io.InputStream; public Image getLogoFromAssets(Context context) { try { // 注意assets里的路径是相对assets根目录的 InputStream inputStream = context.getAssets().open("images/logo.png"); Image image = Image.getInstance(inputStream); // 可选:按比例缩放50% image.scalePercent(50); return image; } catch (IOException | BadElementException e) { e.printStackTrace(); return null; } }
最后要注意的细节
- 确保资源存在:检查文件名大小写(Android资源文件名是大小写敏感的),不要有空格或特殊字符。
- 正确添加到PDF:获取到Image后,要在
document.open()之后、document.close()之前调用document.add(image),不然也会出错。 - 内存优化:如果是大图,建议先压缩再转换,避免出现OOM问题。
内容的提问来源于stack exchange,提问作者Otavio Miguel




