有时候,一个男人只需要知道如何真正理解他一遍又一遍地读到的东西。。。
ppkapperances文件中包含了所有内容。在遵守他们推荐的词典结构方面,我甚至没有达到预期的程度。
我只需要添加n1和n3层,流内容甚至可以只是“%DS空白”。你找到的问号字符串流就是我从中提取的
PdfSignatureAppearance.cs
文件来自
iText
解决方案如果我使用一个Foxit阅读器,它会显示问号(即使签名有效)。对于Adobe来说,我使用它或
DSBlank
.
require 'openssl'
begin
require 'origami'
rescue LoadError
ORIGAMIDIR = "C:\RailsInstaller\Ruby1.9.3\lib\ruby\gems\1.9.1\gems\origami-1.2.4\lib"
$: << ORIGAMIDIR
require 'origami'
end
include Origami
def draw_signature(name, attr = {})
load! if @instructions.nil?
x, y = attr[:x], attr[:y]
@instructions << PDF::Instruction.new('q')
@instructions << PDF::Instruction.new('cm', 1, 0, 0, 1, x, y)
@instructions << PDF::Instruction.new('Do', name)
@instructions << PDF::Instruction.new('Q')
end
def SignPdf(inputF)
@inputfile = String.new(inputF)
outputF = @inputfile.insert(inputF.rindex("."),"_signed8")
certFile = "cert.pem"
rsakeyFile = "pk.pem"
passphrase = "mypass"
key4pem=File.read rsakeyFile
key = OpenSSL::PKey::RSA.new key4pem, passphrase
cert = OpenSSL::X509::Certificate.new(File.read certFile)
pdf = PDF.read(inputF)
page = pdf.get_page(1)
#signature image
imageobject = Origami::Graphics::ImageXObject.from_image_file('c:\rails_projects\RecibosOnline\app\assets\images\logo.jpg', 'jpg')
imageobject.Width = 200
imageobject.Height = 141
#formobject = Origami::Graphics::FormXObject.new
#formobject.write("Teste")
width = 300
height=141
x=201
y=186
signedby = "My Company"
location = "Portugal"#pdf.signature[pdf.signature.keys[5]]
contact = "mail@mail.com" #pdf.signature[pdf.signature.keys[6]]
reason = "Testing" #pdf.signature[pdf.signature.keys[7]]
date = Time.now
caption="Digitally Signed By: #{signedby}\nContact: #{contact}\nLocation: #{location}\nReason: #{reason}\nDate: #{date} "
#DSBlankstream= "% DSBLank"
questionMark = "% DSUnknown\n" +
"q\n" +
"1 G\n" +
"1 g\n" +
"0.1 0 0 0.1 9 0 cm\n" +
"0 J 0 j 4 M []0 d\n" +
"1 i \n" +
"0 g\n" +
"313 292 m\n" +
"313 404 325 453 432 529 c\n" +
"478 561 504 597 504 645 c\n" +
"504 736 440 760 391 760 c\n" +
"286 760 271 681 265 626 c\n" +
"265 625 l\n" +
"100 625 l\n" +
"100 828 253 898 381 898 c\n" +
"451 898 679 878 679 650 c\n" +
"679 555 628 499 538 435 c\n" +
"488 399 467 376 467 292 c\n" +
"313 292 l\n" +
"h\n" +
"308 214 170 -164 re\n" +
"f\n" +
"0.44 G\n" +
"1.2 w\n" +
"1 1 0.4 rg\n" +
"287 318 m\n" +
"287 430 299 479 406 555 c\n" +
"451 587 478 623 478 671 c\n" +
"478 762 414 786 365 786 c\n" +
"260 786 245 707 239 652 c\n" +
"239 651 l\n" +
"74 651 l\n" +
"74 854 227 924 355 924 c\n" +
"425 924 653 904 653 676 c\n" +
"653 581 602 525 512 461 c\n" +
"462 425 441 402 441 318 c\n" +
"287 318 l\n" +
"h\n" +
"282 240 170 -164 re\n" +
"B\n" +
"Q\n";
n0 = Annotation::AppearanceStream.new
n0.Type=Origami::Name.new("XObject")
n0.BBox = [ 0, 0, 100, 100 ]
n0.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n0.set_indirect(true)
n0.Resources = Resources.new
n0.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n0.draw_stream('% DSBlank')
#n0.write(Origami::Name.new("% DSBlank"))
n1 = Annotation::AppearanceStream.new
n1.Type=Origami::Name.new("XObject")
n1.BBox = [ 0, 0, 100, 100 ]
n1.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n1.set_indirect(true)
n1.Resources = Resources.new
n1.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n1.draw_stream('% DSBlank')
n3 = Annotation::AppearanceStream.new
n3.Type=Origami::Name.new("XObject")
n3.BBox = [ 0, 0, 100, 100 ]
n3.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n3.set_indirect(true)
n3.Resources = Resources.new
n3.Resources.ProcSet = [Origami::Name.new("PDF"),Origami::Name.new("Text"),Origami::Name.new("Text"),Origami::Name.new("ImageB"),Origami::Name.new("ImageC"),Origami::Name.new("ImageI")]
n3.draw_stream('% DSBlank')
n2 = Annotation::AppearanceStream.new
n2.Type = Origami::Name.new("XObject")
#n2.Subtype = Origami::Name.new("Form")
n2.Resources = Resources.new
n2.Resources.ProcSet = [Origami::Name.new("Text")]
n2.set_indirect(true)
n2.Matrix = [ 1, 0, 0, 1, 0, 0 ]
n2.BBox = [ 0, 0, width, height ]
n2.write(caption,:x => 40, :y => height-35, :size => 15)
#n2.draw_stream("q 0 0 198 48 re W n BT /Helv 7.645 Tf 0 g 0 40.135 Td (Digitally ) Tj 28.889 0 Td (signed ) Tj 24.652 0 Td (by ) Tj10.198 0 Td (James ) Tj 24.641 0 Td (Pravetz ) Tj-88.38 -9.174 Td (DN: ) Tj 15.29 0 Td (cn=James ) Tj37.18 0 Td (Pravetz, ) Tj 30.165 0 Td (c=CA, ) Tj 23.156 0 Td0 -9.174 Td (Reason: ) Tj 30.599 0 Td (I ) Tj 4.248 0 Td(have ) Tj 18.702 0 Td (reviewed ) Tj 32.719 0 Td(this ) Tj 14.02 0 Td (document ) Tj -100.288 -9.174 Td(Date: ) Tj 20.397 0 Td (2006.06.08 ) Tj 40.386 0 Td(13:39:35 ) Tj 31.883 0 Td (-07'00') Tj ET Q")
##Sets the root dictionary element
frm = Annotation::AppearanceStream.new
frm.set_indirect(true)
#frm.Type = Origami::Name.new("XObject")
#frm.Subtype = Origami::Name.new("Form")
frm.Resources = Resources.new
frm.Resources.ProcSet = [Origami::Name.new("PDF")]
frm.Resources.add_xobject(Origami::Name.new("n0"), n0)
frm.Resources.add_xobject(Origami::Name.new("n1"), n1)
frm.Resources.add_xobject(Origami::Name.new("n2"), n2)
frm.Resources.add_xobject(Origami::Name.new("n3"), n3)
frm.Matrix = [ 1, 0, 0, 1, 0, 0 ]
frm.BBox = [ 0, 0, width, height ]
frm.draw_stream('q 1 0 0 1 0 0 cm /n0 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n1 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n2 Do Q')
frm.draw_stream('q 1 0 0 1 0 0 cm /n3 Do Q')
xo17 = Annotation::Widget::Signature.new
#xo17 = Annotation::Widget::Signature.new
xo17.Rect = Rectangle[ llx: x, lly: y, urx: x+width, ury: y+height ]
#xo17.Resources = Resources.new
#xo17.Resources.add_xobject(Origami::Name.new("FRM"), frm)
xo17.F = Annotation::Flags::PRINT #sets the print mode on
xo17.H = Annotation::Widget::Highlight::INVERT
streamN = Annotation::AppearanceStream.new #.setFilter(:FlateDecode)
streamN.set_indirect(true)
streamN.BBox = [ 0, 0, width, height ]
streamN.Resources = Resources.new
streamN.Resources.ProcSet = [Origami::Name.new("PDF")]
streamN.Resources.add_xobject(Origami::Name.new("FRM"), frm)
streamN.Subtype = nil
#cs = ContentStream.new('q 1 0 0 1 0 0 cm /FRM Do Q',streamN)
streamN.draw_stream('q 1 0 0 1 0 0 cm /FRM Do Q')
#streamN.draw_image(Origami::Name.new("FRM"),{x:x,y:y})
#streamN.write(caption,:x => 40, :y => height-35, :size => 15)
xo17.set_normal_appearance(streamN)
# page.add_xobject(Origami::Name.new("FRM"),frm)
# page.add_xobject(Origami::Name.new("n0"),n0)
# page.add_xobject(Origami::Name.new("n2"),n2)
page.add_annot(xo17)
# Sign the PDF with the specified keys
pdf.sign(cert, key,
:method => 'adbe.pkcs7.sha1',
:annotation => xo17,
:location => location,
:contact => contact,
:reason => reason
)
# Save the resulting file
pdf.save(outputF)
end
SignPdf("Sample.pdf")
多么激烈的战斗!
我想说:
最终,胜利者是那些站在战场中央的人。悲伤地看着他们周围的战场,想知道为什么会这样。只有当他们知道如何阅读。。。那么这些事情就不会发生了。然而,与此同时,如果这件事没有发生,他们就不知道自己不知道如何以正确的焦点阅读。