ある PDF ファイルから別の PDF ファイルに注釈をコピーする必要があります。優れた PDFClown ライブラリを使用しましたが、色、回転などを操作できません。これは可能ですか? baseobject 情報を確認できますが、それを直接操作する方法もわかりません。
外観の複製で外観をコピーできますが、「編集」できません。
前もって感謝します。アレックス
PSステファノがリストしている場合、プロジェクトは死んでいますか?
ある PDF ファイルから別の PDF ファイルに注釈をコピーする必要があります。優れた PDFClown ライブラリを使用しましたが、色、回転などを操作できません。これは可能ですか? baseobject 情報を確認できますが、それを直接操作する方法もわかりません。
外観の複製で外観をコピーできますが、「編集」できません。
前もって感謝します。アレックス
PSステファノがリストしている場合、プロジェクトは死んでいますか?
私はそれを少し調べましたが、高レベルの方法を使用して任意の入力に対して決定論的に操作できるものはあまりないのではないかと思います. その理由は、Callout 注釈の外観を設定するための代替方法が多数あり、PDF Clown は明示的な高レベル メソッドを使用した優先度の低い方法のみをサポートするためです。優先度の高いものから下へ
APストリームでの明示的な出現。指定されている場合は、この外観が Callout 注釈のように見えるかどうか、ましてや他の Callout プロパティで定義されたものと同じように見えるかどうかを無視して使用されます。
PDF Clown は、特定の属性 (例: Color
) の変更に対応するために既存の外観を更新するどころか、他の値から吹き出し注釈の外観をまだ作成していません。ISO 32000-2 のサポートについては、アピアランス ストリームが必須になったため、PDF Clown を改善する必要があります。
存在する場合は、を使用して外観を取得できますが、取得できるのは低レベルの描画命令getAppearance()
のみFormXObject
で、Callout 固有のものはありません。
ただし、与えられた a を非常に簡単に操作できることの 1 つは、それに応じてMatrixFormXObject
を設定することで、外観を非常に簡単に回転または傾斜させることができます。
annotation.getAppearance().getNormal().get(null).setMatrix(AffineTransform.getRotateInstance(100, 10));
RC文字列またはストリーム内のリッチ テキスト文字列。外観が指定されていない限り、吹き出しテキスト ボックス内のテキストは、このリッチ テキスト データムから生成されます (ここでのリッチ テキストは、書式設定に XHTML 1.0 サブセットを使用します)。
Color
PDF Clown は、吹き出しテキストのリッチ テキスト表現をまだ作成していません。ましてや、特定の属性 (例: ) の変更に対応するために既存のものを更新することはできません。
存在する場合は、 を使用して低レベル アクセスでリッチ テキストを取得し、getBaseDataObject().get(PdfName.RC)
この文字列またはストリームを変更して、 を使用して再度設定できgetBaseDataObject().put(PdfName.RC, ...)
ます。PdfName.DS
同様に、代わりにその名前を使用して、リッチ テキストの既定のスタイル文字列を取得、操作、および設定できます。
アピアランス ストリームと (テキスト コンテンツに関する限り) リッチ テキスト文字列がない場合に、Callout を構築するために使用される個別の側面のさまざまな設定。
PDF Clown は、これらの属性 (の多く) をサポートします。特に、複製された注釈を にキャストする場合StaticNote
、たとえば、不透明度CAを使用してget/set/withAlpha
、ボーダー ボーダー/ BSを使用してget/set/withBorder
、背景色Cを使用してget/set/withColor
...
ちなみに、行末スタイルのLEサポートにエラーがあります。どうやら、行注釈LEプロパティのコードがチェックせずにコピーされたようです。残念ながら、その属性は別の構文に従います...
したがって、変更したいと言った属性については、
Rotation : Callout アノテーション自体には回転属性はありません (ページの回転に従うかどうかのフラグ以外)。したがって、回転を単純な注釈属性として設定することはできません。ただし、ソース アノテーションに外観ストリームがある場合は、そのマトリックスを操作して、アノテーションの四角形内で回転させることができます。上記を参照してください。
境界線の色とフォント: Callout に外観ストリームがある場合は、 を使用してコンテンツを解析し、ContentScanner
色とフォントの設定操作を操作できます。それ以外の場合、リッチ テキスト情報が設定されている場合は、フォントについて、何らかの XML パーサーを使用してリッチ テキストを解析し、フォント スタイル属性を操作することができます。それ以外の場合は、デフォルトの外観DA文字列を解析し、そのフォントと色の設定命令を操作できます。
Adobe Acrobat を使用して Callout 注釈の例を含むファイルを作成しました: Callout-Yellow.pdf。これには外観ストリーム、リッチ テキスト、および単純な属性が含まれているため、このファイルをさまざまなレベルでの操作などに使用できます。
このコードをkeepAppearanceStream
andに異なる値を付けて適用しましたkeepRichText
(Java と .Net のどちらに PDF Clown を使用したかは言及されていませんでした。そのため、Java を選択しました。.Net へのポートは簡単なはずですが...):
boolean keepAppearanceStream = ...;
boolean keepRichText = ...;
try ( InputStream sourceResource = GET_STREAM_FOR("Callout-Yellow.pdf");
InputStream targetResource = GET_STREAM_FOR("test123.pdf");
org.pdfclown.files.File sourceFile = new org.pdfclown.files.File(sourceResource);
org.pdfclown.files.File targetFile = new org.pdfclown.files.File(targetResource); ) {
Document sourceDoc = sourceFile.getDocument();
Page sourcePage = sourceDoc.getPages().get(0);
Annotation<?> sourceAnnotation = sourcePage.getAnnotations().get(0);
Document targetDoc = targetFile.getDocument();
Page targetPage = targetDoc.getPages().get(0);
StaticNote targetAnnotation = (StaticNote) sourceAnnotation.clone(targetDoc);
if (keepAppearanceStream) {
// changing properties of an appearance
// rotating the appearance in the appearance rectangle
targetAnnotation.getAppearance().getNormal().get(null).setMatrix(AffineTransform.getRotateInstance(100, 10));
} else {
// removing the appearance to allow lower level properties changes
targetAnnotation.setAppearance(null);
}
// changing text background color
targetAnnotation.setColor(new DeviceRGBColor(0, 0, 1));
if (keepRichText) {
// changing rich text properties
PdfString richText = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.RC);
String richTextString = richText.getStringValue();
// replacing the font family
richTextString = richTextString.replaceAll("font-family:Helvetica", "font-family:Courier");
richText = new PdfString(richTextString);
targetAnnotation.getBaseDataObject().put(PdfName.RC, richText);
} else {
targetAnnotation.getBaseDataObject().remove(PdfName.RC);
targetAnnotation.getBaseDataObject().remove(PdfName.DS);
}
// changing default appearance properties
PdfString defaultAppearance = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.DA);
String defaultAppearanceString = defaultAppearance.getStringValue();
// replacing the font
defaultAppearanceString = defaultAppearanceString.replaceFirst("Helv", "HeBo");
// replacing the text and line color
defaultAppearanceString = defaultAppearanceString.replaceFirst(". . . rg", ".5 g");
defaultAppearance = new PdfString(defaultAppearanceString);
targetAnnotation.getBaseDataObject().put(PdfName.DA, defaultAppearance);
// changing the text value
PdfString contents = (PdfString) targetAnnotation.getBaseDataObject().get(PdfName.Contents);
String contentsString = contents.getStringValue();
contentsString = contentsString.replaceFirst("text", "text line");
contents = new PdfString(contentsString);
targetAnnotation.getBaseDataObject().put(PdfName.Contents, contents);
// change the line width and style
targetAnnotation.setBorder(new Border(0, new LineDash(new double[] {3, 2})));
targetPage.getAnnotations().add(targetAnnotation);
targetFile.save(new File(RESULT_FOLDER, "test123-withCalloutCopy.pdf"), SerializationModeEnum.Standard);
}
( CopyCallOutテストtestCopyCallout
)
コードには概念実証の品質しかないことに注意してください: 任意の PDF の場合、単に "font-family:Helvetica" を "font-family:Courier" に、または "Helv" を "HeBo" または ". ..rg" ごとに ".5 g" を実行してください: フォントは、さまざまなスタイル属性または名前を使用して指定でき、さまざまな色指定を使用できます。