How to generate searchable PDF using swift - ios

Right now I am able to generate a PDF using the code below. The issue is that the generated PDF is not searchable nor its texts copyable. (like the whole PDF is a image).
Is there a way to create a PDF using ios (Swift) that has its texts copyable/searchable?
Part of my code that generates the pdf:
let pdfFrame:CGRect = CGRect(x: 0, y: 0, width: sourceView.contentSize.width, height: sourceView.contentSize.height);
UIGraphicsBeginPDFContextToFile(dataFilename, pdfFrame, nil);
UIGraphicsBeginPDFPageWithInfo(pdfFrame, nil);
sourceView.contentOffset = CGPoint.zero;
sourceView.frame = pdfFrame;
let pdfContext : CGContext = UIGraphicsGetCurrentContext()!;
sourceView.layer.render(in: pdfContext);
UIGraphicsEndPDFContext();

In order to generate a PDF that is searchable, you need to create a PDF file that contains text. Your PDF is being created only with images. You can't use render(in:). Whatever text you want in the PDF needs to be drawn into the PDF context. See How to draw text in PDF context in Swift? for an example.

Related

How to make image source change after handle without display another one on canvas output (OpenCV.js)

I am using OpenCV.js in Ionic 3 to make a scanner app.
I have a .ts file with rotate function like this:
rotateRight() {
let src = cv.imread('img');
let dst = new cv.Mat();
let dsize = new cv.Size(src.rows, src.cols);
let center = new cv.Point(src.cols / 2, src.rows / 2);
let M = cv.getRotationMatrix2D(center, -90, 1);
cv.warpAffine(src, dst, M, dsize, cv.INTER_LINEAR, cv.BORDER_CONSTANT, new cv.Scalar());
cv.imshow('canvasOutput', dst);
src.delete(); dst.delete(); M.delete();
}
And I have code like this in .html file with img source to get and canvas to display new image after processing:
<img id="img" [src]="picture" *ngIf="picture" />
<canvas id="canvasOutput" ></canvas>
My problem is I just want to display only one image in my .html file, I want after processing the new image will display in the img source from the begin instead of having another display like canvas.
Is there any way to do that?
Thanks for helping!
After asking I found the answer by myself.
Firstly, get element canvasOutput and img from HTML, then change image's source to canvasOutput with base64 format:
var canvasOutput = document.getElementById('canvasOutput') as HTMLCanvasElement;
let picture = document.getElementById("img") as HTMLImageElement;
picture.src = canvasOutput.toDataURL();
Lastly set 's style to visibility: hidden to hide canvas tag.

Is it possible to draw a pdf vector image inside a larger pdf page?

I have a pdf vector file that I want to display as part of a pdf document. I don't really want to change it to an UIImage file. I just feel that doing so will degrade the quality. What Im attempting to do is take the url of the pdf and add it to the main pdf document. I've worked out the size of my pdf vector and created a CGRect as follows:
func drawPDFfromURL(url: NSURL) {
guard let document = CGPDFDocumentCreateWithURL(url) else { return nil }
guard let page = CGPDFDocumentGetPage(document, 1) else { return nil }
let pageRect = CGPDFPageGetBoxRect(page, .MediaBox)
let size = pageRect.size
pdfImagePageRect = CGRectMake(0, 0, size.width, size.height)
print("The size of the pdf is \(size)")
}
I then thought of just using the following but realised I cant because UIImage does not currently support pdf vector images
let image:UIImage = UIImage(contentsOfFile: fileName2)!
image.drawInRect(pdfImagePageRect)
I just feel that there must be a way to insert a pdf vector image to a pdf document. Any suggestions?
While UIImage doesn't support PDF files, Apple does provide a way to draw a PDF into a graphics context (whatever it is):
func CGContextDrawPDFPage(_ c: CGContext?, _ page: CGPDFPage?)
This would allow you to get your graphics context for the PDF you are writing, open your second PDF file, get a reference to the page and have the page rendered into your PDF context.
The only hard part is that you need to set the correct transformation matrix so that your PDF file that you are rendering is drawn in the correct location and with the scaling you want.
Also take a look at this page: https://www.cocoanetics.com/2010/06/rendering-pdf-is-easier-than-you-thought/ where it is shown how you can draw the correct part of the incoming PDF file. Essential code at that link is:
// url is a file URL
CGPDFDocumentRef pdf = CGPDFDocumentCreateWithURL((CFURLRef)url);
CGPDFPageRef page1 = CGPDFDocumentGetPage(pdf, 1);
// get the rectangle of the cropped inside
CGRect mediaRect = CGPDFPageGetBoxRect(page1, kCGPDFCropBox);
CGContextScaleCTM(ctx, rect.size.width / mediaRect.size.width,
rect.size.height / mediaRect.size.height);
CGContextTranslateCTM(ctx, -mediaRect.origin.x, -mediaRect.origin.y);
// draw it
CGContextDrawPDFPage(ctx, page1);

Drawing a UIBezierPath to UIImage to Base64 Image not working in Swift

I created some code to create a UIBezierPath within a UIImage context. Then take the image and create a base64 string. I believe I am supposed to draw the path within the beginning and end of the UIImage. However after many hours, it is not working. I am copying the base64 string to a website to download the image to see if it works. I am writing this in playground:
import Foundation
import UIKit
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), false, 0.0)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIColor.blackColor().setStroke()
let path = UIBezierPath()
path.lineWidth = 2
path.moveToPoint(CGPointMake(100, 0))
path.addLineToPoint(CGPointMake(200, 40))
path.addLineToPoint(CGPointMake(160, 140))
path.addLineToPoint(CGPointMake(40, 140))
path.addLineToPoint(CGPointMake(0, 40))
path.closePath()
UIGraphicsEndImageContext();
let data = UIImagePNGRepresentation(image)
let b64 = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
print(b64!)
The resulting PNG is 1000x1000 I am guessing because of my retina display. The image itself is completely transparent and nothing is visible. I am using this site to decode base64 and save a file, I've tried 2 others to see if it was the site. http://www.motobit.com/util/base64-decoder-encoder.asp
EDIT
I just tried the following code to see if the issue with with my image or bezier or saving to bas64. This code worked great. So I think it's a problem with my bezier.
import Foundation
import UIKit
let image = UIImage(data: NSData(contentsOfURL: NSURL(string: "http://i.imgur.com/crr4m48.jpg")!)!)!
let data = UIImagePNGRepresentation(image)
let b64 = data?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
print(b64!)
It looks like you're doing things out of order. For example:
UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 200), false, 0.0)
let image = UIGraphicsGetImageFromCurrentImageContext()
Why are you getting image before you draw anything into the graphics context? I think you're going to get an empty image -- it's not like the image you get at the outset will change as you draw things in the context. Wait to get the image until after you finish all your drawing. Also, the docs for that function say:
You should call this function only when a bitmap-based graphics context is the current graphics context. If the current context is nil or was not created by a call to UIGraphicsBeginImageContext, this function returns nil.
So, make sure that you've satisfied that requirement and that the image you get back when you do call UIGraphicsBeginImageContext() is not nil.
Next, you're creating a bezier path:
let path = UIBezierPath()
path.lineWidth = 2
path.moveToPoint(CGPointMake(100, 0))
path.addLineToPoint(CGPointMake(200, 40))
//...
but in order for that path to actually be drawn in your context, you have to do something that draws, such as calling path.fill() or path.stroke(). I don't see that anywhere, so even if you fix the first problem above, you're still going to end up with an empty image until you do some drawing.
You need to work with the image context directly. You can try create CGContextRef with current image context like:
UIGraphicsBeginImageContext(CGSizeMake(200, 200))
var context: CGContextRef = UIGraphicsGetCurrentContext()
And then directly add your path to it:
CGContextAddPath(context, path)
Or you can create you curves with context methods like CGContextAddCurveToPoint and then stroke path with:
CGContextStrokePath(context)
And the last action to create image from it:
let image = UIGraphicsGetImageFromCurrentImageContext()
One more Point In addition to #Caleb :-
If you are drawing image.png which result of 1000x1000 pixels then UIGraphicsBeginImageContext parameter must be different as above one :-
//Swift-3 Syntax
UIGraphicsBeginImageContextWithOptions( CGSize(width:500, height:500 ), false , 2.0 )
Reference

Using Bootstrap Glyph icons in iTextSharp

I am building a .NET/C#/MVC system that uses Bootstrap and iTextSharp.
I have two Glyph font icons that I would also like to use when generating a PDF document using iTextSharp.
The only way I know to include and image in a PDF, is to designate a stream to an image:
Stream imageStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Onlineeksamen.Web.Resources.ios7-phone1-icon.png");
Image image = Image.GetInstance(imageStream);
The Glyph icons are available in following files:
fonts\glyphicons-halflings-regular.eot
fonts\glyphicons-halflings-regular.svg
fonts\glyphicons-halflings-regular.ttf
fonts\glyphicons-halflings-regular.woff
I now have following sample based on the comment from jme but it doesnt work - I assume that the icons are characters in the font:
outputStream = new MemoryStream();
document = new Document(PageSize.A4, margin, margin, margin, margin);
pdfWriter = PdfWriter.GetInstance(document, outputStream);
document.Open();
pdfContentByte = pdfWriter.DirectContent;
PageHeight = document.PageSize.Height;
pdfContentByte.SetColorStroke(BaseColor.BLACK);
string fontFile = String.Format("{0}fonts\\glyphicons-halflings-regular.ttf", HostingEnvironment.ApplicationPhysicalPath);
BaseFont customfont = BaseFont.CreateFont(fontFile, BaseFont.CP1252, BaseFont.EMBEDDED);
pdfContentByte.SetFontAndSize(customfont, 12);
pdfContentByte.BeginText();
pdfContentByte.SetTextMatrix(100, PageHeight.Value - 100);
pdfContentByte.ShowText("This should be glyphs");
pdfContentByte.EndText();
document.Close();
return outputStream.ToArray();
Thank you in advance
Soeren D.

iOS Drawing image issue

I'm try to create application where I'm use a UIScrolView and I can draw different jpeg images on the appropriate point for each of this images. It is must looks like a video, for example:
I have a first jpeg image (background), and this image (for example image has coordinates: x = 0, y = 0, and dimentions: width = 1024, height = 768), I send to UIScrolView for showing. Then I get enother jpeg image with their own coordinatates and dimentions(for example x = 10, y = 10, width = 100, height = 100) and I need show this "smal" image over "background".
How I can di that?
Or another way of this issue. Example:
I have a BMP data of first image(bacground). How I can send this BMP data to the UIScrolView for showing?\
P.S. One more question: Which of presented above ways will run faster for processing and presentation of data?
WBR
Maxim Tartachnik

Resources