public class OutputProfiler extends Object implements Runnable
An OutputProfiler
is used to create an OutputProfile
for a PDF or to
attempt to apply a new OutputProfile, modifying the PDF in the process. This can
be a basic OutputProfile, which is very quick to create, or a full
OutputProfile which involves scanning the entire PDF, and takes much longer.
This class now underlies the PDF.getBasicOutputProfile()
and PDF.getFullOutputProfile()
methods, and brings several advantages; you can re-run the profile when you know
the PDF has changed, you can create the profile in one thread and monitor its progress in another,
and you can make structural changes to the PDF (such as substituting fonts or colors) that aren't
possible with the previous API.
To create a new profile with the same information as PDF.getBasicOutputProfile()
:
OutputProfiler profiler = new OutputProfiler(pdf); OutputProfile profile = profiler.getProfile();and to duplicate the functionality of the
PDF.getFullOutputProfile()
method:
OutputProfiler profiler = new OutputProfiler(new PDFParser(pdf)); OutputProfile profile = profiler.getProfile();To duplicate the functionality of the
PDF.setOutputProfile(org.faceless.pdf2.OutputProfile)
method, you would call
apply(org.faceless.pdf2.OutputProfile)
. For example, to retrieve the full profile of the PDF, check if it's
compatible with a "target" profile and attempt to convert the PDF to that profile if not:
OutputProfiler profiler = new OutputProfiler(new PDFParser(pdf)); OutputProfile profile = profiler.getProfile(); OutputProfile.Feature[] list = profile.isCompatibleWith(target); if (list != null) { profiler.apply(target); }
This is an oversimplified example, as typically converting a PDF to a profile (known
as "preflighting") requires more information. The OutputProfiler
class
allows you to specify various actions to perform on the PDF when converting -
if specified these will involve a rebuild of the entire document, which can be time-
consuming.
As an example, assume a PDF has an embedded font in it - this is not allowed in PDF/A. To try to convert the PDF to PDF/A-1b, you could run the following code:
PDF pdf = new PDF(new PDFReader(new File("unembeddedfont.pdf"))); OutputProfiler profiler = new OutputProfiler(new PDFParser(pdf)); OutputProfile profile = profiler.getProfile(); ICC_Profile icc = ICC_Profile.getInstance(ColorSpace.CS_sRGB); OutputProfile target = new OutputProfile(OutputProfile.PDFA1b_2005, "sRGB", null, "http://www.color.org", null, icc); OutputProfile.Feature[] list = profile.isCompatibleWith(target); if (list != null) { profiler.apply(target); // This line will fail }
This will fail with an
IllegalStateException
("Denied Feature 'Unembedded TrueType Font' is set").
To fix this you need to set an action on the OutputProfiler
before you apply the
new profile. This will cause the PDF to be rebuilt internally. Here's how the above example
could be modified to replace some, or all unembedded fonts with an embedded font from the OS.
PDF pdf = new PDF(new PDFReader(new File("unembeddedfont.pdf"))); OutputProfiler profiler = new OutputProfiler(new PDFParser(pdf)); OutputProfile profile = profiler.getProfile(); ICC_Profile icc = ICC_Profile.getInstance(ColorSpace.CS_sRGB); OutputProfile target = new OutputProfile(OutputProfile.PDFA1b_2005, "sRGB", null, "http://www.color.org", null, icc); OutputProfile.Feature[] list = profile.isCompatibleWith(target); if (list != null) { OutputProfiler.AutoEmbeddingFontAction fontaction = new OutputProfiler.AutoEmbeddingFontAction(); fontaction.add(new OpenTypeFont(new FileInputStream("C:\\Windows\\Fonts\\arial.ttf"), 2)); profiler.setFontAction(fontaction); profiler.apply(target); }
OutputProfile
Modifier and Type | Class and Description |
---|---|
static class |
OutputProfiler.AutoEmbeddingFontAction
The
AutoEmbeddingFontAction class is an implementation of OutputProfiler.FontAction that
will replace
unembedded fonts with embedded ones via a "best fit" algorithm. |
static interface |
OutputProfiler.ColorAction
An action that can be
set on an
OutputProfiler to replace Colors. |
static interface |
OutputProfiler.FontAction
An action that can be
set on an
OutputProfiler to replace one font with another in the PDF. |
static class |
OutputProfiler.ImageType
ImageType constants are passed in to the
setMaxImageDPI method |
static class |
OutputProfiler.ProcessColorAction
The
ProcessColorAction class is an implementation of OutputProfiler.ColorAction
which will convert any process colors into the specified ColorSpace. |
static class |
OutputProfiler.RenderingIntent
RenderingIntent constants are passed in to the
OutputProfiler.ProcessColorAction.setRenderingIntent(org.faceless.pdf2.OutputProfiler.RenderingIntent) method |
Constructor and Description |
---|
OutputProfiler()
Create a new OutputProfiler
|
OutputProfiler(PDF pdf)
Create a new OutputProfiler and call
setPDF() |
OutputProfiler(PDFParser parser)
Create a new OutputProfiler and call
setParser() |
Modifier and Type | Method and Description |
---|---|
void |
apply(OutputProfile targetprofile)
Set the specified
OutputProfile on the PDF. |
void |
cancel()
Cancel this OutputProfiler's operation - if it is being run in another
thread, that thread should terminate safely shortly after this method
is called.
|
OutputProfile |
getProfile()
Return the
OutputProfile calculated by the run() method. |
float |
getProgress()
Return the progress of the
run() operation, or 0 if this is not being
run, has completed or has been cancelled. |
boolean |
isCancelled()
Return true if the
cancel() method has been called. |
boolean |
isDone()
Return true if the
run() method has completed or been cancelled,
false if it's still running or has not yet been started. |
boolean |
isRunning()
Return true if the
run() method is running in another thread,
and false if it has completed, been cancelled or not yet started. |
void |
run()
Analyze the PDF and generate its profile.
|
void |
setColorAction(OutputProfiler.ColorAction action)
Set the
OutputProfiler.ColorAction to run on the PDF. |
void |
setFontAction(OutputProfiler.FontAction action)
Set the
OutputProfiler.FontAction to run on the PDF. |
void |
setFull(boolean full)
Sets whether the OutputProfiler will create a full OutputProfile when it is run.
|
void |
setHairlineWidth(float width)
|
void |
setMaxImageDPI(OutputProfiler.ImageType imagetype,
float threshold,
float target)
Set the maximum image resolution to be used in the PDF.
|
void |
setParser(PDFParser parser)
Set the PDFParser to create the OutputProfile from.
|
void |
setPDF(PDF pdf)
Set the PDF to create the OutputProfile from.
|
OutputProfile |
waitForProfile()
Wait for the profiling operation running in this (or another) thread to finish,
and return the profile when done.
|
public OutputProfiler()
public OutputProfiler(PDF pdf)
setPDF()
pdf
- the PDFpublic OutputProfiler(PDFParser parser)
setParser()
parser
- the PDFParserpublic void setPDF(PDF pdf)
pdf
- the PDF to scan for featuressetParser(org.faceless.pdf2.PDFParser)
,
setFull(boolean)
public void setParser(PDFParser parser)
parser
- the PDFParser containing the PDF to scan for featuressetPDF(org.faceless.pdf2.PDF)
,
setFull(boolean)
public void setFull(boolean full)
PDFParser
and calls setParser(org.faceless.pdf2.PDFParser)
full
- whether to extract a full profile from the PDF.public void run()
PDFParser
was specified on this class, either in the constructor or by calling setParser(org.faceless.pdf2.PDFParser)
.
If available a full profile will be run, which can take some time. If not, a
basic profile is generated which is essentially instantaneous.run
in interface Runnable
isRunning()
,
getProfile()
public void cancel()
isCancelled()
public boolean isRunning()
run()
method is running in another thread,
and false if it has completed, been cancelled or not yet started.run()
public boolean isDone()
run()
method has completed or been cancelled,
false if it's still running or has not yet been started.public boolean isCancelled()
cancel()
method has been called.isRunning()
public OutputProfile getProfile()
OutputProfile
calculated by the run()
method. If run()
has not been called already, it will be called by this method. If it has already completed,
it will return the result (or null
if it failed). If it is currently running
in another thread, this method will return null
immediately.isRunning()
public OutputProfile waitForProfile()
isRunning()
public float getProgress()
run()
operation, or 0 if this is not being
run, has completed or has been cancelled.isRunning()
public void setHairlineWidth(float width)
Hairlines
are denied when a new profile
is applied
, they will be changed to lines of the specified width.
This will rebuild the PDF. If no hairlines are present in the PDF when
this method is called, no rebuild will be performed.width
- the width to use to replace any hairlines. Must be > 0public void setFontAction(OutputProfiler.FontAction action)
OutputProfiler.FontAction
to run on the PDF. This can be used to replace fonts in
the PDF with new fonts.
Calling this method will cause the PDF to be rebuilt in apply()
.action
- the FontActionpublic void setColorAction(OutputProfiler.ColorAction action)
OutputProfiler.ColorAction
to run on the PDF. This can be used to replace colors in
the PDF.
Calling this method will cause the PDF to be rebuilt in apply()
.action
- the ColorActionpublic void setMaxImageDPI(OutputProfiler.ImageType imagetype, float threshold, float target)
apply()
.imagetype
- the ImageType whether this applies to one-bit, gray or color imagestarget
- the resolution to test the image against - all copies of the image embedded
in the PDF must be this resolution or higher for it to be resampled.target
- the resolution to resample the image to.public void apply(OutputProfile targetprofile)
Set the specified OutputProfile
on the PDF. The supplied "target" profile
will have a number of features denied
and required
,
and this method will {attempt to modify the PDF to match those requirements. If it's
not possible then an IllegalStateException
will be thrown.
If the supplied profile references any features that require a full scan and the PDF
has been loaded in (rather than create from scratch), then a full profile of the
existing PDF must be run()
to determine which features are currently set. If
this is already in progress
in another thread, this method will
wait for it to complete. If it hasn't yet been started, it will be started on this
thread by calling getProfile()
. If no PDFParser
has been set (in the
constructor or through the setParser
method) then a full profile cannot
be created, and an IllegalStateException
will be thrown.
If a OutputProfiler.FontAction
or OutputProfiler.ColorAction
has been set on this class or
setMaxImagePI
has been called, an extra stage will be
run which rebuilds the PDF content. It is also run if the full profile
shows up any hairlines
and the
setHairlineWidth
method was calling with a non-zero value.
After this stage, or if no actions or hairline-replacement are specified, then the method will attempt to modify the PDF to add or remove required or denied features, as specified in the target profile. If that completes successfully, the OutputIntent on the target profile will be applied to the PDF and this method will complete.
targetprofile
- the OutputProfile that this PDF should be converted to match.Copyright © 2001-2017 Big Faceless Organization