PDFsharp & MigraDoc Foundation http://forum.pdfsharp.com/ |
|
changing text color http://forum.pdfsharp.com/viewtopic.php?f=2&t=1281 |
Page 1 of 1 |
Author: | pirosu [ Thu Jul 29, 2010 1:13 pm ] |
Post subject: | changing text color |
If I open an exsisting pdf document, can I change the color of part of the text, chosen by me? |
Author: | jccapps [ Fri Aug 06, 2010 3:31 pm ] |
Post subject: | Re: changing text color |
I found a way to do this, but it isn't easy (if you find an easier way please post your solution). What I found is that you'll have to read the text directly from the PdfPage's stream. You then search through the stream line by line looking for the op codes that draw the text and set its color. You will then change the parameters for text's color op code. To find the op codes you are looking for you'll have to look them up from either the PDFSharp source code or the Adobe PDF Spec. My requirement was to create a program to convert all the RGB vector data in a PDF to CMYK using predefined conversion values. Here is some prototype code I wrote to accomplish this. You might can change it to work for just text: private void ConvertDocToCMYK() { PdfDocument rgbdoc = PdfReader.Open("C:\\pdf\\NebraskaDOR(rgb).pdf", PdfDocumentOpenMode.Modify); PdfPage rgbpage = rgbdoc.Pages[0]; //get all the internal objects from the pdf PdfObject[] obj = rgbdoc.Internals.GetAllObjects(); //loop through all of those objects looking for streams for (int i = 0; i < obj.Length; i++) { PdfDictionary dict = (PdfDictionary)obj[i]; //if the object doesn't contain a stream then just skip it if (dict.Stream != null) { //there should also not be a subtype if this stream contains vector data??? object subType = dict.Elements["/Subtype"]; if (subType == null) { PdfDictionary.PdfStream stream = dict.Stream; //decode the stream bool pass = stream.TryUnfilter(); string temp = stream.ToString(); //look for the op-codes and change values ParseString(ref temp); //re encode the dtream byte[] b = PdfDictionary.PdfStream.RawEncode(temp); PdfInteger integer = new PdfInteger(b.Length); //set the old stream to null, do we need to dispose of this some how??? dict.Stream = null; //set the length of the new stream dict.Elements["/Length"] = integer; //create the new stream dict.CreateStream(b); //delete the old dictionary from the page rgbdoc.Internals.RemoveObject(obj[i]); //add the dictionary we just created rgbdoc.Internals.AddObject(dict); } } } rgbdoc.Options.ColorMode = PdfColorMode.Cmyk; rgbdoc.Save("C:\\pdf\\testconvert.pdf"); } private void ParseString(ref string stream) { string temp; string r, g, b, c, m, y, k; int beginIndex, endIndex, lineIndex; int rBeginIndex, rEndIndex, gBeginIndex, gEndIndex, bBeginIndex, bEndIndex; //rg is the op code for drawing in RGB, find all instances of this and change to CMYK while (stream.Contains(" rg")) { endIndex = stream.IndexOf(" rg") + 3; bEndIndex = endIndex - 3; temp = stream.Substring(0, bEndIndex); bBeginIndex = temp.LastIndexOf(" "); b = temp.Substring(bBeginIndex, bEndIndex - bBeginIndex); gEndIndex = bBeginIndex; temp = temp.Substring(0, gEndIndex); gBeginIndex = temp.LastIndexOf(" "); g = temp.Substring(gBeginIndex, gEndIndex - gBeginIndex); rEndIndex = gBeginIndex; temp = temp.Substring(0, rEndIndex); rBeginIndex = temp.LastIndexOf(" "); lineIndex = temp.LastIndexOf("\n") + 1; if (rBeginIndex < lineIndex) rBeginIndex = lineIndex; r = temp.Substring(rBeginIndex, rEndIndex - rBeginIndex); beginIndex = rBeginIndex; ConvertRGBToCMYK(r, g, b, out c, out m, out y, out k); stream = stream.Remove(beginIndex, endIndex - beginIndex); stream = stream.Insert(beginIndex, c + " " + m + " " + y + " " + k + " k"); } //also check for the capitalized version while (stream.Contains(" RG")) { endIndex = stream.IndexOf(" RG") + 3; bEndIndex = endIndex - 3; temp = stream.Substring(0, bEndIndex); bBeginIndex = temp.LastIndexOf(" "); b = temp.Substring(bBeginIndex, bEndIndex - bBeginIndex); gEndIndex = bBeginIndex; temp = temp.Substring(0, gEndIndex); gBeginIndex = temp.LastIndexOf(" "); g = temp.Substring(gBeginIndex, gEndIndex - gBeginIndex); rEndIndex = gBeginIndex; temp = temp.Substring(0, rEndIndex); rBeginIndex = temp.LastIndexOf(" "); lineIndex = temp.LastIndexOf("\n") + 1; if (rBeginIndex < lineIndex) rBeginIndex = lineIndex; r = temp.Substring(rBeginIndex, rEndIndex - rBeginIndex); beginIndex = rBeginIndex; ConvertRGBToCMYK(r, g, b, out c, out m, out y, out k); stream = stream.Remove(beginIndex, endIndex - beginIndex); stream = stream.Insert(beginIndex, c + " " + m + " " + y + " " + k + " K"); } } This may be over kill for what you are trying to do. Maybe somebody else will chime in with a much easier way of changing the color of just the text. |
Page 1 of 1 | All times are UTC |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |