Skip to content

Instantly share code, notes, and snippets.

@datalogics-pgallot
Last active September 1, 2017 17:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save datalogics-pgallot/3cedf862533310bb1cde493c0d09de54 to your computer and use it in GitHub Desktop.
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.
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