質問者
PDFファイルに埋め込まれているグリフとテキストの関係を変更したい。

質問
-
PDFファイル内にフォントが埋め込まれているとします。
例えばの話ですが、「αβγδ」とPDF上では表示されているのに、その部分をPDFビュワーなどのアプリで選択してコピーすると、「abgd」というテキストが取得できるものがあります。
これは、見た目のグリフとテキストが一致しないフォントが埋め込まれているという事になります。こういうフォントは少数ではあると思いますがそれなりに存在すると思います。Symbolフォントなどがそうでしょうか。
PDFの見た目はそのままにして、グリフと対応するテキストを変更したいのですが、このような事を行う方法はありますでしょうか?
上記の例でいいますと、PDFファイルをプログラムで読み込んで特定のフォントの「αβγδ」というグリフに対応するテキストを「abgd」から「αβγδ」に変更するという処理を行いたいのです。
VB.NETあるいはC#で開発したいと思っています。
どうぞ、よろしくお願いいたします。
すべての返信
-
C#でSymbol Fonts⇔Unicode変換ははこんな感じでしょうか?(もっと簡単な方法があるかもしれませんが・・・)
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace WindowsFormsApplication1 { public class SymbolToUnicodeConverter { readonly int[] table = { 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 32, 33,8704, 35,8707, 37, 38,8717, 40, 41,8727, 43, 44,8722, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 8773, 913, 914, 935, 916, 917, 934, 915, 919, 921, 977, 922, 923, 924, 925, 927, 928, 920, 929, 931, 932, 933, 962, 937, 926, 936, 90, 91,8756, 93,8869, 95, 63, 945, 946, 967, 948, 949, 966, 947, 951, 953, 981, 954, 955, 956, 957, 959, 960, 952, 961, 963, 964, 965, 982, 969, 958, 968, 950, 123, 124, 125, 126, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 978,8242,8804,8260,8734, 402,9827,9830,9829,9824,8596,8592,8593,8594,8595, 63, 177,8243,8805, 215,8733,8706,8729, 247,8800,8801,8776,8230, 63, 63,8629, 8501,8465,8476,8472,8855,8853,8709,8745,8746,8835,8839,8836,8834,8838,8712,8713,8736,8711, 174, 169,8482,8719,8730,8901, 172,8743,8744,8660,8656,8657,8658,8659, 9674,9001, 174, 169,8482,8721, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,9002,8747,8992, 63,8993, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, }; public string SymbolToUnicode(string symbol) { var unicode = string.Empty; foreach (var s in symbol) { var index = s & 0x0fff; var value = index < table.Length ? table[index] : 63; unicode += Convert.ToChar(value); } return unicode; } } static class Program { [STAThread] static void Main() { SymbolToUnicodeConverter converter = new SymbolToUnicodeConverter(); String str1 = "abcdefghijklmnopqrstuvwxyzABCDEFGEFGHIJKLMNOPQRSTUVWXYZ"; String str2 = converter.SymbolToUnicode(str1); MessageBox.Show(str2); } } }
-
コメントありがとうございます。
申し訳ございません。
私のやりたい事はPDFファイルを開いてグリフとテキストの関係を変更し,新たにPDFを保存するというものです。
PDF内のグリフ情報へのアクセス,変更,保存などPDFまわりの手段を探しています。
説明不足で誠に申し訳ございませんでした。
こちらこそ勘違いでした。申し訳ございません。
ご存知かもしれませんが、PDFを開いて編集し再保存するMicorosoftの標準的なものはまだ存在しないようです。Windows 8.1から使うことができるWindows.Data.PdfもPDFデータの文字列の編集・保存までは対応していないようです。
そこでサードパーティ製のPDF読み込み保存機能のあるライブラリですが、有名なところでは「iTextSharp」、「PDFSharp」というライブラリがあるそうです。
以上、参考になりましたら幸いです。
-
何がしたいのか、よくわかんない。
HTML で、「<p style="font-family:Century;">abgd</p>」と、「<p style="font-family:Symbol;">abgd</p>」を表示させると、コードを変えますが、
abgd
αβγδ
のように表示されます。ここで、ギリシャ文字の方をコピーして、メモ帳にペーストすると、「abgd」が表示されます。
・・・ということでしょうか?そういうことならば、PDF 規格を入手して、ファイルを解析し、フォントを指定している部分を置き換えれば良いと思います。
なんか、違う気がするなぁ。
「見た目のグリフとテキストが一致しないフォント」
「PDFの見た目はそのままにして、グリフと対応するテキストを変更したい」
「特定のフォントの「αβγδ」というグリフに対応するテキストを「abgd」から「αβγδ」に変更する」
「グリフとテキストの関係を変更」
このあたりが、わからない。「グリフ」「テキスト」「フォント」の定義が違っているように思う。「abgd」は、キャラクターコードでそれぞれ 0x61 0x62, 0x67, 0x64 なわけで、このキャラクターコードを Symbols というフォントを使うと、ギリシャ文字として表示される。つまり、「αβγδ」という“データ”は、「0x61 0x62, 0x67, 0x64」という“内容”と、「Symbols フォントを使って表示する」という“指示”によって成り立っている。そこから「0x61 0x62, 0x67, 0x64」という内容だけ取り出して、Gothic や Serif のフォントで表示すれば「abgd」になる。
Adobe Reader では、コピーしたときに Text だけでなく、Rich TextFormat も作成していました。Rich TextFormat の方をリッチテキストを再現できるものにペーストすれば、「αβγδ」は「αβγδ」で見えると思います。まぁ、クリップボードデータを作るアプリケーションと、そこからデータを取り出すアプリケーションと、それぞれのアプリケーション次第なのですが。
蛇足。Word に「abgd」を入力し、フォントを Symbols に変更、コピーすると、内容が「0xf061, 0xf062, 0xf067, 0xf064」に変わる。なんでじゃ?
Jitta@わんくま同盟
-
なんだか、セキュリティツール(コピペができないPDFをつくるツール)が作りたいのかな、という感じがします。
その前提でうろ覚えレベルの話をします。(PDF仕様を参照して下さい。)
PDFの文字描画、というのは面倒くさくて、というのもフォント埋め込み有り無しの他に、文字コードが複数あることによります。
明らかに、フォントを埋め込まない場合、描画はOSに頼むしかないので、コピペを防止するのは無理ですね。
次に文字コードですが、SJIS,UNICODE,CIDの3種類があったはずです。で埋め込まれているフォントの中に、CID<->UNICODEの変換テーブルとかがあって、コピペの際は内蔵変換テーブルでUNICODEに変換がかかった気がします。
もう判りましたよね。Text描画のデータを適当に変換して、それに合うように埋め込まれたフォントのテーブルをいじってやればいい、という話です。(埋め込まれていない場合にフォントを埋め込む方法と、フォントのライセンスについての楽しい話は除きます)。
たとえば、UNICODEの’あ'を、CID=95とかに変換して、フォントの'あ'というグリフを指すように埋め込みフォントを変換し、埋め込みフォント中のUNICODEの逆変換テーブルは’N'を返すように作えればよい、ということです。PDFの生データとかフォントをゴリゴリバイナリで編集する必要があるでしょう。
ライブラリがあるのかどうかは判然としません。
jzkey
-
みなさん、ありがとうございます。
意図が伝わらなかったようで申し訳ございません。
PDFファイルがあり、「あ」という形の文字が表示されています。
この「あ」をAcrobat Readerなどで選択コピーし、テキストエディタに貼ると「A」となってしまう状態のものがあります。
このグリフとテキストデータのコードポイントの関係を変更したいのです。
現在「iTextSharp」で調べ始めたところですが、可能か不可能かの判断までは到達していません。
kenjinote様からお教えいただいた「PDFSharp」については全く調べていませんので、「iTextSharp」に挫折した場合は調査してみようと思います。
取り急ぎ、お礼まで。
-
VB User1 さま 拝見しました。 PDF 上で ですね。
abcd αβγδ フォント で検索するとギリシャ文字みたいですね。
でしたら、αβγδ を αβγδ U+03B1~U+03B4 に置換しては如何でしょうか?。 そうなっているから表示されるのかな?。 メモ帳(フォント MS ゴシック/メイリオ)でも全角ですが表示されます。
或いは、上記コードがちゃんとギリシャ文字になる(Unicode も Shift-JIS もコード記載がある)フォントに変更するかですね。 IME パッド等で確認出来る筈です。
https://ja.wikipedia.org/wiki/%E3%82%AE%E3%83%AA%E3%82%B7%E3%82%A2%E6%96%87%E5%AD%97
因みに、ですが。 コピー先のフォントを別のものに変更すると正確に表示している 等と言う おち は無いですよね。
- 編集済み ShiroYuki_Mot 2016年4月2日 6:30 因みに 追記
-
うーん、逆の話でしたか。
前述したとおり、埋め込みフォントの描画であれば、PDFリーダーソフトは、PDF文書中の「座標X,YにフォントFでグリフ番号1,2,3,3,4,5を描画してね」という指示に従って描画をしておしまいです。埋め込まれたフォントFのグリフ番号1が「A」の形をしていようが「α」のかたちをしていようが何かのロゴであろうが、関知しません。
では、PDFで埋め込みフォントを選択してコピーした場合にどんな文字列になるか、という話ですが、PDF仕様の9.10 Extraction of Text Contentに記載があります。
ここでは簡単のために、PDFにType-1フォントとして埋め込まれたものと考えてみましょう(なので日本語は除外)。
PDF中にはフォント定義と中身(グリフ)がありますが、フォント定義にToUnicodeエントリーが定義されている場合、そこで指示されたstreamがCMAPファイルであると解釈され、cmapをつかってグリフ番号とUNICODEの変換がなされます。そうでない場合、フォントのエンコーディング情報から、グリフ番号とUNICODEの変換がなされます。どれにも当てはまらないばあい、どうしようもありません。(コピーしようとしても、空の文字列になると思われる)では、この埋め込みフォントのマッピングがおかしいPDFをどうすれば修正できるのでしょうか。一番汎用であろうのは、グリフを実際に描画して、人に判断させる手ですね。で、一通り埋め込みフォントのただしいUNICODEが解ったら、CMAPを作成して、ToUnicodeエントリを追加する、という手になるかとおもいます。
何度も言いますが、あまりに低水準な話なのでライブラリの内部クラスを持ってくるとか(圧縮とかstreamとdisctionaryとかのベースサポート)、「PDFをバイト単位で自分で操作する」くらいの覚悟でないと出来ない気がします。
jzkey