c# - Change object's color inside existiong PDF with iTextSharp -
major part of job automation of engineering process, have create simple program, compares 2 different version of 1 drawn element, overlapping drawings, in order review differences. drawings represent single sheet pdf files.
i'm using .net framework , c# 4.5;
itextsharp library editing pdf files;
initially, i'm getting 2 files, read them , create third one, contains result;
var file1 = "file1.pdf"; var file2 = "file2.pdf"; var result = "result.pdf"; using (stream f1stream = new filestream(file1, filemode.open)) using (stream f2stream = new filestream(file2, filemode.open)) using (stream resultstream = new filestream(result, filemode.create, fileaccess.readwrite)) using (pdfreader f2reader = new pdfreader(f2stream)) using (pdfreader f1reader = new pdfreader(f1stream)) { pdfstamper pdfstamper = new pdfstamper(f1reader, resultstream); pdfcontentbyte pdfcontentbyte = pdfstamper.getovercontent(1); var page = pdfstamper.getimportedpage(f2reader, 1); pdfcontentbyte.addtemplate(page,2,2); pdfstamper.close(); }
the code above makes that, few sequential questions arising
- i want change color of elements in result file i.e. elements come 1st drawing in green , others 2nd 1 - in red color. maybe have change color of entities in initial 2 pdfs , merge;
- initial files have layers, , because 2 sequential revision of same construction element , differences between them few, have identical layers. , want have " layerfoo " , " layerfoo@ " in result pdf. maybe have rename layers in 1 the 2 initial pdfs , merge them.
Аll suggestions welcomed including usage of library :)
--> edit1 big chris haas! absolutely right token type , string value! itextrups great helping tool understanding structure of pdf files. following code taken post pointed me out.
the following statement:
stream.setdata(system.text.encoding.ascii.getbytes(string.join("\n", newbuf.toarray())));
updates stream of file ,
using (var fs = new filestream(file2, filemode.create, fileaccess.write, fileshare.none)) { var stamper = new pdfstamper(reader, fs); reader.setpagecontent(1,reader.getpagecontent(1)); stamper.close(); }
the new file created updated stream.
i made 1 simple test file 2 lines, change color , save new file. no problem! after that, tried same simple operation real file, represents real drawing of construction element, result file less half of original , broken. comes mind updated stream saved new file other information inside other containers not saved, it's stream.
because stuck that, continue next step of investigation -> layers wrote code in order available layers in pdf file. try insert more records layers dictionary see happen.
var resourcesreference = page.get(pdfname.resources) pdfindirectreference; var resources = pdfreader.getpdfobject(resourcesreference) pdfdictionary; var propertiesobjhectreferences = resources.get(pdfname.properties); var properties = pdfreader.getpdfobject(propertiesobjhectreferences) pdfdictionary; foreach (var property in properties.keys) { var layerreference = properties.get(property); var layerobject = pdfreader.getpdfobject(layerreference) pdfdictionary; foreach (var key in layerobject.keys) { if (key.tostring()!=pdfname.type.tostring()) { var layername = layerobject.getasstring(key).tounicodestring(); } } }
if come main goal top of post, tends insert stream , layers first file second in order obtain result file, contains objects previous 2, painted in different colors + layers both.
feel free suggest me another, more simpler , beautiful solution! happy if revise code , correct it! thank much!
edit 2
i simplify work because lack of time, change color of entities inside 1 pdf , put on background on other.
const string pdf = "file1.pdf"; var reader = new pdfreader(pdf); var page = reader.getpagen(1); var objectreference = page.get(pdfname.contents) pdfindirectreference; var stream = (prstream)pdfreader.getpdfobject(objectreference); var streambytes = pdfreader.getstreambytes(stream); var tokenizer = new prtokeniser(new randomaccessfileorarray(streambytes)); var newbuf = new list<string>(); while (tokenizer.nexttoken()) { var token = tokenizer.stringvalue; newbuf.add(token); if (tokenizer.tokentype == prtokeniser.toktype.other && newbuf[newbuf.count - 1].equals("s", stringcomparison.currentcultureignorecase)) { newbuf.insert(newbuf.count - 1, "0"); newbuf.insert(newbuf.count - 1, "1"); newbuf.insert(newbuf.count - 1, "1"); newbuf.insert(newbuf.count - 1, "rg"); } } var resultstream = string.join("\n", newbuf.toarray()); stream.setdata(system.text.encoding.ascii.getbytes(resultstream)); var file2 = pdf.insert(pdf.length - 4, "result"); using (var fs = new filestream(file2, filemode.create, fileaccess.write, fileshare.none)) { var stamper = new pdfstamper(reader, fs); reader.setpagecontent(1, reader.getpagecontent(1)); stamper.close(); }
result pdf broken , itextrups throws exception when try stream data page.
Comments
Post a Comment