首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在使用PyFPDF创建pdf时增加透明度

如何在使用PyFPDF创建pdf时增加透明度
EN

Stack Overflow用户
提问于 2019-07-23 09:12:28
回答 2查看 1.8K关注 0票数 0

我使用,PyFPDF来生成PDF。我希望向我使用PyFPDF创建的矩形添加透明度。

我在fpdf文档中找到了允许我们添加透明度- 纯种性的PHP代码。我试着遵循这一点,并在python中编写代码,但是它没有工作。

文档中的代码片段(在PHP中):

代码语言:javascript
复制
<?php
require('fpdf.php');

class AlphaPDF extends FPDF
{
    var $extgstates = array();

    // alpha: real value from 0 (transparent) to 1 (opaque)
    // bm:    blend mode, one of the following:
    //          Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
    //          HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
    function SetAlpha($alpha, $bm='Normal')
    {
        // set alpha for stroking (CA) and non-stroking (ca) operations
        $gs = $this->AddExtGState(array('ca'=>$alpha, 'CA'=>$alpha, 'BM'=>'/'.$bm));
        $this->SetExtGState($gs);
    }

    function AddExtGState($parms)
    {
        $n = count($this->extgstates)+1;
        $this->extgstates[$n]['parms'] = $parms;
        return $n;
    }

    function SetExtGState($gs)
    {
        $this->_out(sprintf('/GS%d gs', $gs));
    }

    function _enddoc()
    {
        if(!empty($this->extgstates) && $this->PDFVersion<'1.4')
            $this->PDFVersion='1.4';
        parent::_enddoc();
    }

    function _putextgstates()
    {
        for ($i = 1; $i <= count($this->extgstates); $i++)
        {
            $this->_newobj();
            $this->extgstates[$i]['n'] = $this->n;
            $this->_out('<</Type /ExtGState');
            $parms = $this->extgstates[$i]['parms'];
            $this->_out(sprintf('/ca %.3F', $parms['ca']));
            $this->_out(sprintf('/CA %.3F', $parms['CA']));
            $this->_out('/BM '.$parms['BM']);
            $this->_out('>>');
            $this->_out('endobj');
        }
    }

    function _putresourcedict()
    {
        parent::_putresourcedict();
        $this->_out('/ExtGState <<');
        foreach($this->extgstates as $k=>$extgstate)
            $this->_out('/GS'.$k.' '.$extgstate['n'].' 0 R');
        $this->_out('>>');
    }

    function _putresources()
    {
        $this->_putextgstates();
        parent::_putresources();
    }
}
?>

使用

代码语言:javascript
复制
<?php
require('alphapdf.php');

$pdf = new AlphaPDF();
$pdf->AddPage();
$pdf->SetLineWidth(1.5);

// draw opaque red square
$pdf->SetFillColor(255,0,0);
$pdf->Rect(10,10,40,40,'DF');

// set alpha to semi-transparency
$pdf->SetAlpha(0.5);

// draw green square
$pdf->SetFillColor(0,255,0);
$pdf->Rect(20,20,40,40,'DF');

// draw jpeg image
$pdf->Image('lena.jpg',30,30,40);

// restore full opacity
$pdf->SetAlpha(1);

// print name
$pdf->SetFont('Arial', '', 12);
$pdf->Text(46,68,'Lena');

$pdf->Output();
?>

这就是我在python中所写的:

代码语言:javascript
复制
class EXPDF(FPDF):

  def __init__(self, orientation='P', unit='mm', style='A4'):
    super(EXPDF, self).__init__(orientation=orientation, unit=unit, format=style)
    self.page_format = style.lower()
    self.extgstates = {}

  def set_alpha(self, alpha, bm='Normal'):
    gs = self.add_ext_gstate({'ca': alpha, 'CA': alpha, 'BM': '/'+bm})
    self.set_ext_gstate(gs)

  def add_ext_gstate(self, parms):
    n = len(self.extgstates.keys())+1
    if n not in self.extgstates.keys():
      self.extgstates[n] = { 'parms': parms }
    else:
      self.extgstates[n]['parms'] = parms
    return n

  def set_ext_gstate(self, gs):
    self._out(sprintf('/GS%d gs', gs))

  def _enddoc(self):
    if self.extgstates and self.pdf_version < '1.4':
      self.pdf_version = '1.4'
    super()._enddoc()

  def _putextgstates(self):
    for i in range(1, len(self.extgstates.keys())+1):
      self._newobj()
      self.extgstates[i]['n'] = self.n
      self._out('<</Type /ExtGState')
      parms = self.extgstates[i]['parms']
      self._out(sprintf('/ca %.3F', parms['ca']))
      self._out(sprintf('/CA %.3F', parms['CA']))
      self._out('/BM'+parms['BM'])
      self._out('>>')
      self._out('endobj')

  def _putresourcedict(self):
    super()._putresourcedict()
    self._out('/ExtGState <<')
    for k in self.extgstates:
      self._out('/GS'+str(k)+' '+str(self.extgstates[k]['n'])+' O R')
    self._out('>>')

使用

代码语言:javascript
复制
pdf = EXPDF()
pdf.set_alpha(0.5)
pdf.rectangle(20, 20, 40, 40, 'DF')

当我运行它时,代码没有抛出任何错误。但是当我试图打开Acrobat中生成的pdf时,上面写着There was a problem reading this document (135)。我试着在google chrome中打开pdf。它打开了,但矩形仍然是不透明的。

EN

回答 2

Stack Overflow用户

发布于 2019-09-17 06:59:40

我认为您的python代码有几个错误:

  1. 它缺少_putresources方法。
  2. 在方法_putresourcesdict中,下面一行的大写字母为O,而不是0。因此,请改为0 R
代码语言:javascript
复制
self._out('/GS'+str(k)+' '+str(self.extgstates[k]['n'])+' O R')
票数 0
EN

Stack Overflow用户

发布于 2020-07-22 19:19:35

您需要这样一个类(pyFPDF使用https://github.com/reingart/pyfpdf):

代码语言:javascript
复制
class PDF (fpdf.FPDF):
    def __init__ (self, orientation = 'P', unit = 'mm', format = 'A4'):
     self.__extgstates = []
     super().__init__ (orientation, unit, format)

# alpha: real value from 0 (transparent) to 1 (opaque)
# bm:    blend mode, one of the following:
#          Normal, Multiply, Screen, Overlay, Darken, Lighten, ColorDodge, ColorBurn,
#          HardLight, SoftLight, Difference, Exclusion, Hue, Saturation, Color, Luminosity
def set_alpha(self, alpha, bm='Normal'):
    # set alpha for stroking (CA) and non-stroking (ca) operations
    data = {'ca':alpha,'CA':alpha,'BM':'/' + bm, 'n' : 0}
    gs = self.add_ext_gstate(data)
    self.set_ext_gstate(gs + 1)

def add_ext_gstate(self, data):
    n = len(self.__extgstates)
    self.__extgstates.append(data)
    return n

def _enddoc(self):
    if len(self.__extgstates) > 0 and self.pdf_version < '1.4':
        self.pdf_version ='1.4'
    super()._enddoc()

def set_ext_gstate(self, gs):
    self._out('/GS%d gs' % (gs))

def _putextgstates(self):
    i = 0
    while i < len(self.__extgstates):
        self._newobj()
        self._out('<</Type /ExtGState')
        self.__extgstates[i]["n"] = self.n
        parms = self.__extgstates[i]
        self._out('/ca %.3F' % (parms["ca"]))
        self._out('/CA %.3F' % (parms["CA"]))
        self._out('/BM ' + parms["BM"])
        self._out('>>')
        self._out('endobj')
        i += 1

def _putresourcedict(self):
    super()._putresourcedict()
    self._out('/ExtGState <<')
    for index, eg in enumerate(self.__extgstates):
        self._out('/GS' + str(index + 1) + ' ' + str(eg["n"])  + ' 0 R')
    self._out('>>')

def _putresources(self):
    self._putextgstates()
    super()._putresources()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57160660

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档