-
-
Save datalogics-pgallot/3cedf862533310bb1cde493c0d09de54 to your computer and use it in GitHub Desktop.
This program demonstrates how to Clip images to fit a string of Text.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Text; | |
using Datalogics.PDFL; | |
/* | |
* | |
* This program demonstrates how to Clip images to fit a string of Text. | |
* | |
* Copyright (c) 2007-2017, Datalogics, Inc. All rights reserved. | |
* | |
* For complete copyright information, refer to: | |
* http://dev.datalogics.com/adobe-pdf-library/license-for-downloaded-pdf-samples/ | |
* | |
*/ | |
namespace ImageImportSample | |
{ | |
class ImageImportSample | |
{ | |
static Rect CalculateMarginRect(Rect basisRect, double leftMargin, double bottomMargin, double rightMargin, double topMargin) | |
{ | |
return new Rect(basisRect.Left + leftMargin, | |
basisRect.Bottom + bottomMargin, | |
basisRect.Right - rightMargin, | |
basisRect.Top - topMargin); | |
} | |
static Matrix calcMatrixToFitTextToRect(Font f, Rect fitRect, String fitText, TextState ts) | |
{ | |
var result = new Matrix(1, 0, 0, 1, 0, 0); // identity matrix. | |
var gs = new GraphicState(); | |
var dummyTR = new TextRun(fitText, f, gs, ts, result); | |
var adv = dummyTR.Advance; | |
var scaleFactor = Math.Min(fitRect.Height - 2, fitRect.Width / adv); | |
result.Dispose(); | |
var leftOffset = fitRect.Left + ((fitRect.Width - (adv * scaleFactor)) / 2.0); // horizontally centered | |
result = new Matrix(scaleFactor, 0, 0, scaleFactor, leftOffset, fitRect.Bottom); | |
dummyTR.Dispose(); | |
gs.Dispose(); | |
return result; | |
} | |
static Rect[] CalcTextClipBoundingBoxes(Font f, String fitText, TextState ts, Matrix tm) | |
{ | |
List<Rect> Boxes = new List<Rect>(); | |
var gs = new GraphicState(); | |
var curM = tm; | |
foreach(var c in fitText) | |
{ | |
var dummyTR = new TextRun(c.ToString(), f, gs, ts, curM); | |
Boxes.Add(dummyTR.BoundingBox); | |
curM = curM.Translate(dummyTR.Advance, 0); | |
dummyTR.Dispose(); | |
} | |
return Boxes.ToArray(); | |
} | |
static Clip[] CreatePerLetterClips(Font f, String fitText, TextState ts, Matrix tm) | |
{ | |
List<Clip> Clips = new List<Clip>(); | |
var gs = new GraphicState(); | |
var curM = tm; | |
foreach (var c in fitText) | |
{ | |
var destClip = new Clip(); | |
var textElem = new Text(); | |
var clipTR = new TextRun(c.ToString(), f, gs, ts, curM); | |
textElem.AddRun(clipTR); | |
destClip.AddElement(textElem); | |
Clips.Add(destClip); | |
curM = curM.Translate(clipTR.Advance, 0); | |
clipTR.Dispose(); | |
textElem.Dispose(); | |
} | |
curM.Dispose(); | |
gs.Dispose(); | |
return Clips.ToArray(); | |
} | |
static Matrix CalcImagePlaceToClip(Image img, double clipLeftPct, double clipBottomPct, double clipRightPct, double clipTopPct, Rect destRect) | |
{ | |
var imgBBox = img.BoundingBox; | |
double clipWidthPct = clipRightPct - clipLeftPct; | |
double clipHeightPct = clipTopPct - clipBottomPct; | |
double clipWidth = imgBBox.Width * clipWidthPct / 100.0; | |
double clipHeight = imgBBox.Height * clipHeightPct / 100.0; | |
double scaleFactorH = destRect.Width / clipWidth; | |
double scaleFactorV = destRect.Height / clipHeight; | |
double scaleFactor = Math.Max(scaleFactorH, scaleFactorV); | |
double imgNewWidth = imgBBox.Width * scaleFactor; | |
double imgNewHeight = imgBBox.Height * scaleFactor; | |
double horizDisp = destRect.Left - (imgNewWidth * clipLeftPct / 100.0); | |
double vertDisp = destRect.Bottom - (imgNewHeight * clipBottomPct / 100.0); | |
return new Matrix(imgNewWidth, 0, 0, imgNewHeight, horizDisp, vertDisp); | |
} | |
static Text outlineText(string outlineText, TextState ts, Matrix textMatrix,Font f, GraphicState gs) | |
{ | |
var textElem = new Text(); | |
ts.RenderMode = TextRenderMode.Stroke; | |
var tr = new TextRun(outlineText, f, gs, ts, textMatrix); | |
textElem.AddRun(tr); | |
return textElem; | |
} | |
static void prebaked(Document doc, Font curFont, string clipText) | |
{ | |
var postcrdRect = new Rect(0, 0, 72 * 6, 72 * 4); | |
var postcrdMarginRect = CalculateMarginRect(postcrdRect, 9, 9, 9, 9); | |
var vOffset = 18; | |
string[] imgsPaths = new string[] | |
{ | |
@"C:\Image\ChicagoPix\IMG_1192.JPG", | |
@"C:\Image\ChicagoPix\IMG_1283.JPG", | |
@"C:\Image\ChicagoPix\PICT0069.JPG", | |
@"C:\Image\ChicagoPix\P1010320.JPG", | |
@"C:\Image\ChicagoPix\PICT0016.JPG", | |
@"C:\Image\ChicagoPix\PICT0018.JPG", | |
@"C:\Image\ChicagoPix\DSC_0570.JPG" | |
}; | |
double[,] crops = new double[,]{ | |
{40,20,100,80}, | |
{44,35,84,100}, | |
{40,20,90,90}, | |
{25,30,80,80}, | |
{20,20,75,80}, | |
{20,0,80,90}, | |
{29,33,71,87}, | |
}; | |
var TextColor = new Color(1, 0, 0); | |
Dictionary<int, Image> images = new Dictionary<int, Image>(); | |
for (int i = 0; i < imgsPaths.Length; i++) | |
{ | |
images.Add(i, new Image(imgsPaths[i], doc)); | |
} | |
int numImages = images.Count; | |
var ts = new TextState(); | |
var ClipTextContent = new Content(); | |
var OutlineGS = new GraphicState(); | |
var BKGDImg = new Image(@"C:\Image\ChicagoPix\IMG_1172.JPG", doc); | |
BKGDImg.Matrix = CalcImagePlaceToClip(BKGDImg, 20, 23, 80, 63, postcrdRect); | |
var docpage = doc.CreatePage(Document.LastPage, postcrdRect); | |
var pgContent = docpage.Content; | |
pgContent.AddElement(BKGDImg); | |
var textMatrix = calcMatrixToFitTextToRect(curFont, postcrdMarginRect, clipText, ts); | |
var boxes = CalcTextClipBoundingBoxes(curFont, clipText, ts, textMatrix); | |
var clips = CreatePerLetterClips(curFont, clipText, ts, textMatrix); | |
int numBoxes = boxes.Length; | |
for (int j = 0; j < numBoxes; j++) | |
{ | |
var n = (j % numImages); | |
var subImg = images[n].Clone(); | |
subImg.Matrix = CalcImagePlaceToClip(subImg, crops[n, 0], crops[n, 1], crops[n, 2], crops[n, 3], boxes[n]); | |
subImg.Clip = clips[j]; | |
var formElem = new Form(new Content(subImg), doc); | |
ClipTextContent.AddElement(formElem); | |
subImg.Dispose(); | |
formElem.Dispose(); | |
} | |
var ClipTextForm = new Form(ClipTextContent, doc); | |
ClipTextForm.Matrix = ClipTextForm.Matrix.Translate(0, vOffset); | |
pgContent.AddElement(ClipTextForm); | |
OutlineGS.StrokeColor = TextColor; | |
OutlineGS.Width = 1.5; | |
var textMatrix2 = new Matrix().Translate(0, vOffset).Concat(textMatrix); | |
Text textOutline = outlineText(clipText, ts, textMatrix2, curFont, OutlineGS); | |
pgContent.AddElement(textOutline); | |
textMatrix.Dispose(); | |
var bannerRect = new Rect(postcrdMarginRect.Left, | |
postcrdMarginRect.Top - 0.15 * postcrdMarginRect.Height, | |
postcrdMarginRect.Right, | |
postcrdMarginRect.Top); | |
ts.RenderMode = TextRenderMode.FillThenStroke; | |
var gs = new GraphicState(); | |
gs.FillColor = TextColor; | |
gs.StrokeColor = new Color(0); | |
var bannerText = "Greetings From"; | |
textMatrix = calcMatrixToFitTextToRect(curFont, bannerRect, bannerText, ts); | |
var bannerTR = new TextRun(bannerText, curFont, gs, ts, textMatrix); | |
var bannerTextElem = new Text(); | |
bannerTextElem.AddRun(bannerTR); | |
pgContent.AddElement(bannerTextElem); | |
docpage.UpdateContent(); | |
pgContent.Dispose(); | |
textOutline.Dispose(); | |
OutlineGS.Dispose(); | |
ClipTextForm.Dispose(); | |
textMatrix2.Dispose(); | |
textMatrix.Dispose(); | |
bannerTextElem.Dispose(); | |
bannerTR.Dispose(); | |
TextColor.Dispose(); | |
gs.Dispose(); | |
for (int x = numBoxes - 1; x >= 0; x--) | |
{ | |
clips[x].Dispose(); | |
boxes[x].Dispose(); | |
} | |
} | |
static void Main(string[] args) | |
{ | |
Console.WriteLine("TextClipping Sample:"); | |
using (Library lib = new Library()) | |
{ | |
Console.WriteLine("Initialized the library."); | |
Document doc = new Document(); | |
string clipText = "Chicago"; | |
String sOutput = "../ChicagoInPics.pdf"; | |
string[] FontList = { | |
"BlackoakStd","Bauhaus 93","Cooper Black","Forte", | |
"Goudy Stout", "Latin Wide","Old English Text MT", | |
"Poplar Std Black","Ravie","RosewoodStd-Regular", | |
"Showcard Gothic","Snap iTC" | |
}; | |
var letterRect = new Rect(0, 0, 612, 792); | |
var marginRect = CalculateMarginRect(letterRect, 36, 72, 36, 72); | |
var textMaxWidth = marginRect.Width / 2; | |
var textMaxHeight = marginRect.Height / ((FontList.Length + 1) / 2); | |
Dictionary<int, Image> images = new Dictionary<int, Image>(); | |
for (int i = 0; i < args.Length; i++) | |
{ | |
images.Add(i, new Image(args[i], doc)); | |
} | |
int numImages = images.Count; | |
Page docpage = doc.CreatePage(Document.BeforeFirstPage, letterRect); | |
var OutlineGS = new GraphicState(); | |
OutlineGS.StrokeColor = new Color(1, 0, 0); | |
OutlineGS.Width = 1.25; | |
var pgContent = docpage.Content; | |
for (int i = FontList.Length - 1; i >= 0; i--) | |
{ | |
var leftside = marginRect.Left + ((i % 2) * textMaxWidth); | |
var bottomside = marginRect.Bottom + ((i / 2) * textMaxHeight); | |
var testRect = new Rect(leftside, bottomside, | |
leftside + textMaxWidth, bottomside + textMaxHeight); | |
var curFont = new Font(FontList[i], FontCreateFlags.Subset); | |
var ts = new TextState(); | |
var textMatrix = calcMatrixToFitTextToRect(curFont, testRect, clipText, ts); | |
var boxes = CalcTextClipBoundingBoxes(curFont, clipText, ts, textMatrix); | |
var clips = CreatePerLetterClips(curFont, clipText, ts, textMatrix); | |
int numBoxes = boxes.Length; | |
var ClipTextContent = new Content(); | |
for (int j = 0; j < numBoxes; j++) | |
{ | |
var subImg1 = images[(i + j) % numImages].Clone(); | |
subImg1.Matrix = CalcImagePlaceToClip(subImg1, 5, 5, 95, 95, boxes[j]); | |
subImg1.Clip = clips[j]; | |
var formElem = new Form(new Content(subImg1), doc); | |
ClipTextContent.AddElement(formElem); | |
subImg1.Dispose(); | |
formElem.Dispose(); | |
} | |
var ClipTextForm = new Form(ClipTextContent, doc); | |
pgContent.AddElement(ClipTextForm); | |
ClipTextForm.Dispose(); | |
ClipTextContent.Dispose(); | |
for (int x = numBoxes - 1; x >= 0; x--) | |
{ | |
clips[x].Dispose(); | |
boxes[x].Dispose(); | |
} | |
Text textOutline = outlineText(clipText, ts, textMatrix, curFont, OutlineGS); | |
pgContent.AddElement(textOutline); | |
textOutline.Dispose(); | |
ts.Dispose(); | |
textMatrix.Dispose(); | |
testRect.Dispose(); | |
curFont.Dispose(); | |
} | |
docpage.UpdateContent(); | |
for (int i = images.Count - 1; i >= 0; i--) | |
{ | |
images[i].Dispose(); | |
images.Remove(i); | |
} | |
pgContent.Dispose(); | |
docpage.Dispose(); | |
OutlineGS.Dispose(); | |
var curFont2 = new Font(FontList[7], FontCreateFlags.Subset); | |
prebaked(doc, curFont2, clipText); | |
doc.EmbedFonts(EmbedFlags.Subset); | |
doc.Save(SaveFlags.Full, sOutput); | |
doc.Close(); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment