5

Reportlab を使用して PDF を生成しています。モデルから写真を取得できません。

#Personal Info             
  p.drawImage('myPhoto.jpg', 40, 730)
  p.drawString(50, 670, 'Your name:' + '%s' % user.name)
  p.drawImage (50, 640, 'Photo: %s' % (user.photo))

PDFの生成時に作成すると、次のエラーが発生しました:

Traceback (most recent call last):
  File "C:\Program Files (x86)\Google\google_appengine\google\appengine\ext\webapp\__init__.py", line 513, in __call__
    handler.post(*groups)
  File "C:\Users\hp\workspace\myApp\src\main.py", line 419, in post
    p.drawImage (50, 640, 'Photo: %s'  %                  (user.photo))
  File "reportlab.zip\reportlab\pdfgen\canvas.py", line 825, in drawImage
  File "reportlab.zip\reportlab\pdfbase\pdfdoc.py", line 2076, in __init__
  File "C:\Python25\lib\ntpath.py", line 189, in splitext
    i = p.rfind('.')
AttributeError: 'int' object has no attribute 'rfind'

写真を呼び出すn.º 419の行にコメントすると、すべてうまくいきます。すでに Datastore Viewer で検査しましたが、モデルは問題ありません。

誰かが何が間違っているのか指摘できますか?

str の代わりに %s を使用する必要がありますか? しかし、同じエラーがスローされます。

4

1 に答える 1

12

ReportLab API リファレンスによると、drawImage() には引数 'image, x, y' がありますが、'x, y, string' を渡しているように見えます。

drawImage() のイメージ引数には、ファイル名または ImageReader が必要です。

この投稿によると、ImageReader コンストラクターはいくつかのタイプの引数を取ることができます。

アップデート:

あなたが投稿したこのコードでは、ImageReader を「image」に割り当てていますが、「imagem」(存在しません) を drawImage に渡しています。

image = ImageReader(user.photo) 
p.drawImage(imagem)

また、user.photo はどのタイプのモデル プロパティですか?

更新 2:

NoneType に関するエラーが発生しています - user.photo が有効な blob であり、None ではありませんか?

また、ブロブは str のサブクラスですが、ImageReader にはStringIOが必要です。そのため、ブロブを StringIO でラップして ImageReader に渡す必要があると思います。次に例を示します。

import StringIO
image = ImageReader(StringIO.StringIO(user.photo))
p.drawImage(image)

ちなみに、私の推測では、アプリ エンジンがサポートしていない (つまり、 urlfetchImageReader('http://www.reportlab.com/rsrc/encryption.gif')ではない) API を使用して、そのサーバーから画像を読み込もうとしている可能性があるため、失敗した可能性があります。

更新 3:

実際には ReportLab のバグのようです。

ReportLab のバージョン 2.4をダウンロードし、utils.pyでこれを見つけました。

def _isPILImage(im):
    try:
        return isinstance(im,Image.Image)
    except ImportError:
        return 0

class ImageReader(object):
    "Wraps up either PIL or Java to get data from bitmaps"
    _cache={}
    def __init__(self, fileName):
        ...
        if _isPILImage(fileName):

ImageReader コンストラクターは _isPILImage を呼び出して、PIL イメージが渡されたかどうかを確認します。ただし、PIL はアプリ エンジンでは使用できないため、Image は None です。そのため、Image.Image を参照すると、表示in _isPILImage AttributeError: 'NoneType' object has no attribute 'Image'.されている がスローされます。

ReportLab を画像で使用する方法を説明しているこのブログ投稿も見つけました。この問題を修正する方法の詳細と、アプリ エンジンで動作させるために必要な別の変更については、「PDF 内の画像」セクションを参照してください。そのブログ投稿の行番号は、私がダウンロードした 2.4 バージョン、またはエラー メッセージの行番号と一致していないようです。そのため、行番号ではなく、記載されているコードを検索してください。

また、PIL を使用しない ReportLab (つまり、アプリ エンジンで実行されるため) は JPEG 画像しか描画できないことにも注意してください (そのブログ投稿にも記載されています)。

最後に、投稿したこのコードで:

def get(self, image): 
    if image is not None: 
        image = ImageReader(StringIO.StringIO(user.photo)) 
        p.drawImage(40, 700, image) 
        p.setLineWidth(.3) 
        p.setFont('Helvetica', 10) 
        p.line(50, 660, 560, 660)

最初の問題は、引数が「image, x, y」である必要があるときに、「x, y, image」で drawImage() を呼び出していることです。

第 2 に、ここでは user も p も定義されていません (そのコードを切り取ったのではないでしょうか?)。

第 3 に、get() にイメージ引数があるのはなぜですか。webapp.WSGIApplication() を作成するときに、URL から何かを解析しますか? そうでない場合、image は None になるため、何も起こりません。

更新 4:

現在Imaging Library not available, unable to import bitmaps only jpegs発生しているエラーは、ReportLab が jpeg を読み取って幅と高さを見つけることができないためです。blob にロードしたときに jpeg が破損したか、ReportLab がサポートしていない形式の jpeg である可能性があります。

ReportLab の lib\utils.py で、次の変更を一時的に試すことができます (バージョン 2.5 の 578 行目あたり)。

try:
    self._width,self._height,c=readJPEGInfo(self.fp)
except:
    raise RuntimeError('Imaging Library not available, unable to import bitmaps only jpegs')

これだけに:

self._width,self._height,c=readJPEGInfo(self.fp)

これにより、スローされている実際の例外をreadJPEGInfo()確認でき、問題の原因を見つけるのに役立つ場合があります。

問題を絞り込むのに役立つもう 1 つの方法は、ユーザー用にアップロードした file.jpg をプロジェクトに配置してから、次のようにすることです。

imagem = canvas.ImageReader(StringIO.StringIO(open('file.jpg', 'rb').read()))

これにより、blob からではなく、ImageReader を使用してファイルから直接 jpeg が読み込まれます。

これが機能する場合、問題はブロブが無効であるため、画像のアップロード コードを確認する必要があります。失敗した場合、jpeg 自体が無効です (または ReportLab でサポートされていません)。

更新 5:

あなたはこれを使用しています:

photo = images.resize(self.request.get('photo'), 32, 32)

このページのサイズ変更に関するドキュメントによると、デフォルトで PNG に設定されている output_encoding 引数を取ります。代わりにこれを試してください:

photo = images.resize(self.request.get('photo'), 32, 32, images.JPEG)
于 2010-09-28T07:56:20.057 に答える