Itext7 manipulate Dictionary for Fonts - itext7

I'd like to ask a question about the relationship between PdfDictionary Fonts and the Stream.
I have this piece of code to add a font into a page's dictionary:
private void addFonts(PdfDocument pdfa, String fontPath) throws IOException {
PdfDictionary font;
FontProgram fontProgram = FontProgramFactory.createFont(fontPath);
FontProgramFactory.registerFont(fontPath);
PdfFont fontNew = PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, EmbeddingStrategy.PREFER_EMBEDDED);
fontNew.setSubset(true);
for (int i = 0; i <= pdfa.getNumberOfPdfObjects(); i++) {
PdfObject obj = pdfa.getPdfObject(i);
if (obj != null && !obj.isDictionary()) {
continue;
}
font = (PdfDictionary) obj;
if (font != null) {
font.put(PdfName.Font, fontNew.getPdfObject());
System.out.println(font);
}
}
pdfa.addFont(fontNew);
}
This is the result:
I ask:
1- Why is the font also added outside the resources? (blue)
2- How can I change the name /F47 (I know that itext generates it automatically) in /F1 (since in the stream there are references to /F1 /F2 /F3) (green)
3- In general how can I generate fonts
"/F1"
"/F2"
"/F3"
and change the references in the stream

Related

Find and use already embedded font?

I have create a PDF file with Adobe Illustrator that I have loaded into memory with itext7 pdfreader.
That PDF file already contains a embedded font named "Lato (Embedded)" Encoding:Ansi.
How do create a PDFFont object out of it so I and can use it to draw additional paragraphs?
First of all please note that you would only be able to write additional paragraphs with such a fond if the subset contains all the glyphs needed to write the text, or if the font was fully embedded into the PDF.
The solution below works in case the font you want to find is used to write at least one glyph in the content stream of any page in a document (including nested XObjects), and in case you don't have other fonts with similar names in the document.
Here is a small utility class that helps you extract the desired font from a document:
private static class FontFinder implements IEventListener {
private PdfFont suitableFont;
private String nameToLookFor;
private FontFinder(String nameToLookFor) {
this.nameToLookFor = nameToLookFor;
}
public static PdfFont findFont(PdfDocument pdfDocument, String fontName) {
FontFinder finder = new FontFinder(fontName);
PdfCanvasProcessor processor = new PdfCanvasProcessor(finder);
for (int i = 1; i <= pdfDocument.getNumberOfPages(); i++) {
processor.processPageContent(pdfDocument.getPage(i));
}
return finder.suitableFont;
}
#Override
public void eventOccurred(IEventData data, EventType type) {
if (data instanceof TextRenderInfo) {
PdfFont curFont = ((TextRenderInfo) data).getFont();
String fontName = curFont.getFontProgram().getFontNames().getFontName();
if (fontName != null && fontName.contains(nameToLookFor)) {
suitableFont = curFont;
}
}
}
#Override
public Set<EventType> getSupportedEvents() {
return new HashSet<>(Arrays.asList(EventType.RENDER_TEXT));
}
}
You will need to open the PdfDocument in stamping mode (passing both PdfReader and PdfWriter to the constructor).
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inFile), new PdfWriter(outFile));
Then you can fetch your font in the following way (make sure result is not null):
PdfFont font = FontFinder.findFont(pdfDocument, "Lato");
After that you can use that font instance to draw any content, e.g. by passing it to setFont method of Paragraph, Div and so on.

How to remove Objects from PDF File using PDFClown

I have a pdf which contains a lot of invisible paths. Since the amount of path produces problems later on, I would like to remove the ones that have white colors.
So far I am trying to do this with a ContentScanner:
public class FilterWhitePathScanner implements Scanner {
private static final Logger LOG = LoggerFactory.getLogger(FilterWhitePathScanner.class);
private int count = 0;
public void scan(ContentScanner level) {
if (level == null)
return;
while (level.moveNext()) {
ContentObject object = level.getCurrent();
if (object instanceof ContainerObject) {
// Scan the inner level!
scan(level.getChildLevel());
} else if (object instanceof org.pdfclown.documents.contents.objects.Path) {
AffineTransform ctm = level.getState().getCtm();
Color<?> strokeColor = level.getState().getStrokeColor();
Color<?> fillColor = level.getState().getFillColor();
if (checkWhite(fillColor) && checkWhite(strokeColor)) {
level.remove();
} else {
LOG.info("Stroke Color " + strokeColor + " - Fill Color " + fillColor);
}
} else {
LOG.info("Object:" + object);
}
}
}
It recognizes the paths correctly, but in the end these are not removed from the PDF. Here the code handling the PDF (it extracts only one page from the source pdf):
Document targetDoc = new File().getDocument();
targetDoc.getPages().add(sourceDoc.getPages().get(pageNum).clone(targetDoc));
Page page = targetDoc.getPages().get(0);
Contents contents = page.getContents();
FilterWhitePathScanner filterWhitePathScanner = new FilterWhitePathScanner();
filterWhitePathScanner.scan(new ContentScanner(contents));
LOG.info("White Paths: " + filterWhitePathScanner.getCount());
targetDoc.getFile().save(tempFilePath.toFile(), SerializationModeEnum.Standard);
The saved PDF file still contains the paths I tried to remove. How can I remove objects from the PDF finally?
Thanks,
Thomas
Finally found the solution in the Java doc:
You have to call contents.flush(); to persist the changes into the pdf file.
So I added this line to the PDF handling code before calling save and it works!

Loading Images from sd card to grid view causes bitmap exceeds VM budget

In my Application im loading images from sd card almost 40 to 50 images in grid view for this i created adapter in which constructor loads images from sd card to global variable of array list of bitmaps with in get view im returning bitmap from array list the problem is from this activity user will move to other activity where he will delete image after deletion user will come back to grid activity and have to load the adapter again this creates "bitmap exceeds vm budget". so i don't know is this way to load images from sd card is there any better approach for that any libraries available for loading images from sd card with out memory leak
public class PicAdapter extends BaseAdapter {
int defaultItemBackground;
private Context galleryContext;
Bitmap placeholder;
public PicAdapter(Context c) {
// instantiate context
galleryContext = c;
// create bitmap array
bitmaplist=new ArrayList<Bitmap>();
GlobalData.imageBitmaps = new WeakReference<ArrayList<Bitmap>>(bitmaplist);
imageDescription = new ArrayList<String>();
imagetitle = new ArrayList<String>();
picturesCursor.moveToFirst();
int i = 0;
for (i = 0; i < picturesCursor.getCount(); i++) {
String imagepath = picturesCursor.getString(picturesCursor
.getColumnIndex("img"));
File cacheimage=new File(imagepath);
if(!cacheimage.exists())
{
dBopenHelper.deleteHappyMoments(imagepath);
}
else
{
Bitmap bitmap =
ViewUtils.decodeSampledBitmapFromResource(imagepath,
AppConstants.FRAME_WIDTH,
AppConstants.FRAME_HEIGHT);
ViewUtils.recycleBitmapFrame();
GlobalData.imageBitmaps.get().add(bitmap);
imageDescription.add(picturesCursor.getString(picturesCursor
.getColumnIndex("image_description")));
imagetitle.add(picturesCursor.getString(picturesCursor
.getColumnIndex("image_title")));
picturesCursor.moveToNext();
}
}
if (i == picturesCursor.getCount()) {
Bitmap bitmap = (Bitmap) BitmapFactory.decodeResource(getResources(), R.drawable.add_new);
GlobalData.imageBitmaps.get().add(bitmap);
imageDescription.add(
"Click Add to new Pictures..............");
}
// get the styling attributes - use default Andorid system resources
}
// BaseAdapter methods
// return number of data items i.e. bitmap images
public int getCount() {
return bitmaplist.size();
}
// return item at specified position
public Object getItem(int position) {
return position;
}
// return item ID at specified position
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = (ImageView) getLayoutInflater().inflate(
R.layout.item_grid_image, null);
convertView.setLayoutParams(new GridView.LayoutParams(
AppConstants.FRAME_WIDTH, AppConstants.FRAME_HEIGHT));
}
galleryImageView = (ImageView) convertView;
galleryImageView.setImageBitmap(GlobalData.imageBitmaps.get().get(position));
public void addPic(Bitmap newPic) {
// set at currently selected index
GlobalData.imageBitmaps.get().add(currentPic, newPic);
}
// return bitmap at specified position for larger display
public Bitmap getPic(int posn) {
// return bitmap at posn index
return GlobalData.imageBitmaps.get().get(posn);
}
}
sample code helps me alot
thanks in advance
If your images have high dimension- you need to display them one by one using some kind of queue.
Make sure that you decode them correctly.

iTextSharp SetListSymbol does not work

I am trying to set styling in PDF generated from iTextSharp.
It seems the SetListSymbol is not working for me whenever I am trying to set Symbol to list items.
Below is the code that I used:
var elements = HTMLWorker.ParseToList(overviewReader,null);
foreach (var element in elements)
{
//element
var list = element as List;
if (list != null)
{
//list.Symbol.GetImage();
list.SetListSymbol("\u25A0");
list.IndentationLeft = 20f;
doc.Add(list);
}
else
{
doc.Add(element);
}
}
The HTMLWorker within iText and iTextSharp supports some very limited "stylesheets" via iTextSharp.text.html.simpleparser.StyleSheet. These stylesheets are loosely based on HTML/CSS properties but only the most basic (think HTML 3.2).
The three main things that you want to do are (1) load a font, (2) create a StyleSheet pointing to that font and (3) bind the StyleSheet to the HTMLWorker. I'm going to partially lift some code from my answer here.
iTextSharp doesn't automatically spider the entire system looking for fonts so you need to manually register them. (Actually, there is a method that you can call and tell iTextSharp to guess at loading fonts but this is much faster.)
Step #1, load the font, in this case Curlz
//Path to our font
string OurFont = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "CURLZ___.TTF");
//Register the font with iTextSharp
iTextSharp.text.FontFactory.Register(OurFont);
Step #2, create a StyleSheet and point it to our font. I'll also set some other properties just to show them off.
//Create a new stylesheet
iTextSharp.text.html.simpleparser.StyleSheet ST = new iTextSharp.text.html.simpleparser.StyleSheet();
//Set the default body font to our registered font's internal name
ST.LoadTagStyle(iTextSharp.text.html.HtmlTags.LI, iTextSharp.text.html.HtmlTags.FACE, "Curlz MT");
ST.LoadTagStyle(iTextSharp.text.html.HtmlTags.LI, iTextSharp.text.html.HtmlTags.COLOR, "FF0000");
ST.LoadTagStyle(iTextSharp.text.html.HtmlTags.LI, iTextSharp.text.html.HtmlTags.SIZE, "50");
Step #3, bind the StyleSheet to our HTMLWorker
//Use our StyleSheet from above when parsing
var elements = HTMLWorker.ParseToList(overviewReader, ST);
Below is a full-working C# WinForms app targeting iTextSharp 5.2.0 that shows off all of the above.
using System;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication2 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
//Path to our font
string FontArial = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "CURLZ___.TTF");
//Register the font with iTextSharp
iTextSharp.text.FontFactory.Register(FontArial);
//Create a new stylesheet
iTextSharp.text.html.simpleparser.StyleSheet ST = new iTextSharp.text.html.simpleparser.StyleSheet();
//Set the default body font to our registered font's internal name
ST.LoadTagStyle(iTextSharp.text.html.HtmlTags.LI, iTextSharp.text.html.HtmlTags.FACE, "Curlz MT");
ST.LoadTagStyle(iTextSharp.text.html.HtmlTags.LI, iTextSharp.text.html.HtmlTags.COLOR, "FF0000");
ST.LoadTagStyle(iTextSharp.text.html.HtmlTags.LI, iTextSharp.text.html.HtmlTags.SIZE, "50");
//Sample HTML
var html = #"<ul><li>Test</li></ul>";
//File to output
var outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf");
//Basic PDF creation, nothing special here
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (Document doc = new Document(PageSize.LETTER)) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
//Bind a reader to our HTML
using (StringReader overviewReader = new StringReader(html)) {
//Use our StyleSheet from above when parsing
var elements = HTMLWorker.ParseToList(overviewReader, ST);
//Loop through each element
foreach (var element in elements) {
//See if the element is a list item
var list = element as List;
if (list != null) {
//Set some properties
list.SetListSymbol("\u25A0");
list.IndentationLeft = 20f;
}
//Add the element to the document
doc.Add(element);
}
}
doc.Close();
}
}
}
this.Close();
}
}
}
List objects = HTMLWorker.ParseToList(new StringReader(format), null);
foreach (IElement element in objects)
{
List list = new List();
list.SetListSymbol("\u2022");
list.IndentationLeft = 20f;
list.Add(element);
if (list.Chunks.Count == 0)
{
doc1.Add(element);
}
else
{
doc1.Add(list);
}
}

Transition of images in Windows Forms Picture box

I'm new to Windows Forms, in my project, i need to change the image in the picture box at runtime. I'm able to do that with the help of a timer. The picture just gets changed. Is it possible to do some transitions when image changes, for example fade in, fade out, blur etc.. If possible could some one please let me know how to do it. I searched in net but in vain.Thanks in advance.
Varun
Simply take new code file and paste below code in it
an original answer for the similar question, answer taken from another question
Answer
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
public class BlendPanel : Panel
{
private Image mImg1;
private Image mImg2;
private float mBlend;
public BlendPanel()
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
}
public Image Image1
{
get { return mImg1; }
set { mImg1 = value; Invalidate(); }
}
public Image Image2
{
get { return mImg2; }
set { mImg2 = value; Invalidate(); }
}
public float Blend
{
get { return mBlend; }
set { mBlend = value; Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
if (mImg1 == null || mImg2 == null)
e.Graphics.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 0, this.Width, this.Height));
else
{
Rectangle rc = new Rectangle(0, 0, this.Width, this.Height);
ColorMatrix cm = new ColorMatrix();
ImageAttributes ia = new ImageAttributes();
cm.Matrix33 = mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg2, rc, 0, 0, mImg2.Width, mImg2.Height, GraphicsUnit.Pixel, ia);
cm.Matrix33 = 1F - mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg1, rc, 0, 0, mImg1.Width, mImg1.Height, GraphicsUnit.Pixel, ia);
}
base.OnPaint(e);
}
}
Build your project. You can now drop a BlendPanel from the top of the toolbox onto your form. Here's a sample program that uses it:
private float mBlend;
private int mDir = 1;
public int count = 0;
public Bitmap[] pictures;
public void myPhoto()
{
pictures = new Bitmap[9];
pictures[0] = new Bitmap(#"Library Images\cf3.jpg");
pictures[1] = new Bitmap(#"Library Images\cf4.jpg");
pictures[2] = new Bitmap(#"Library Images\l1.JPG");
pictures[3] = new Bitmap(#"Library Images\l2.JPG");
pictures[4] = new Bitmap(#"Library Images\l3.JPG");
pictures[5] = new Bitmap(#"Library Images\l4.JPG");
pictures[6] = new Bitmap(#"Library Images\l5.JPG");
pictures[7] = new Bitmap(#"Library Images\l6.JPG");
pictures[8] = new Bitmap(#"Library Images\l7.JPG");
timer1.Interval = 50; //time of transition
timer1.Tick += BlendTick;
try
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
catch
{
}
timer1.Enabled = true;
}
private void BlendTick(object sender, EventArgs e)
{
mBlend += mDir * 0.02F;
if (mBlend > 1)
{
mBlend = 0.0F;
if ((count + 1) < pictures.Length)
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
else
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[0];
count = 0;
}
}
blendPanel1.Blend = mBlend;
}
You'll need to modify the new Bitmap(#"yourimagePath"); calls. Build and run. You should see the displayed image smoothly morph from your first image to your second image without any flickering.
I hope it helps for other...
There is no built-in support for such effects, but you can implement them. I'd suggest to write a custom control that renders the image and have a method for fade-swap, fade itself can be reached with alpha-blending drawing with .NET Graphics class.
However, Graphics class isn't very fast, I don't recommend to use this technique for big images. If you need some fancy UI with hw-accelerated effects, take a look at WPF.
Blend effects are easy to get going by using the ColorMatrix class. There's a good example available in my answer in this thread.
A simple way to get a blur is to resize the image, making it smaller, then redraw it back, making it larger. The Graphics.InterpolationMode property affects the type of blur you'll get.
Those are quicky do-it-yourself solutions. Any decent graphics library has these kind of operations built-in. You probably want something free, check out ImageMagick.NET
To put it simply, not without external (3rd-party) libraries.

Resources