<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Charltsing</title>
    <description>The latest articles on DEV Community by Charltsing (@charltsing).</description>
    <link>https://dev.to/charltsing</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3814035%2Fad478802-c92f-4cc4-a6cd-3ed1e47eb198.jpg</url>
      <title>DEV Community: Charltsing</title>
      <link>https://dev.to/charltsing</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/charltsing"/>
    <language>en</language>
    <item>
      <title>Why Can’t I Copy Text? Understanding Missing ToUnicode Maps in PDFs</title>
      <dc:creator>Charltsing</dc:creator>
      <pubDate>Sun, 22 Mar 2026 07:32:37 +0000</pubDate>
      <link>https://dev.to/charltsing/why-cant-i-copy-text-understanding-missing-tounicode-maps-in-pdfs-52o0</link>
      <guid>https://dev.to/charltsing/why-cant-i-copy-text-understanding-missing-tounicode-maps-in-pdfs-52o0</guid>
      <description>&lt;p&gt;一直以来，经常会有人问我为什么PDF文档中的内容能看到，也能复制，但是粘贴就会乱码。&lt;/p&gt;

&lt;p&gt;例如，一个红楼梦的样本文件，无法通过复制粘贴得到正文文本。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgb1ljve7iygkr3sb0wye.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgb1ljve7iygkr3sb0wye.gif" alt=" " width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;那么，是什么原因造成的乱码呢？我用AI分析这个文档，看一下字符是如何被渲染到页面上面的。&lt;/p&gt;

&lt;p&gt;首先，我们用&lt;a href="https://github.com/Charltsing/oPDF" rel="noopener noreferrer"&gt;oPDF&lt;/a&gt;，看一下文档的内容流，你会看到类似的操作符&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue651vohqd8neoqum2jh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fue651vohqd8neoqum2jh.png" alt=" " width="390" height="135"&gt;&lt;/a&gt;&lt;br&gt;
这段指令的意思是，使用C0_0字体，渲染0003字符到指定位置。&lt;/p&gt;

&lt;p&gt;AI分析结果如下：&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8efkesav9tus6m9vhsdo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8efkesav9tus6m9vhsdo.PNG" alt=" " width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;通过分析，我们知道了0003字符是从字体文件 /FontFile3 中读取字形，并渲染的。所以我们可以正确的看到这个字。&lt;/p&gt;

&lt;p&gt;那么，为什么复制粘贴就乱码了呢？这就要提到一个字体中的概念----Unicode映射。字体文件的本质就是矢量绘图，而复制粘贴需要知道文字的Unicode码，把这个码放到剪贴板里面，其它的软件才会知道是什么字。&lt;/p&gt;

&lt;p&gt;正规的字体文件，都会带一个Unicode映射表，这个表会告诉软件字体中的第几个字对应的是Unicode中的哪一个字的编码。然后我们才能正确地复制粘贴。&lt;/p&gt;

&lt;p&gt;所以，PDF文档为什么复制粘贴之后就会乱码的原因，想必你也清楚了。正是由于某些PDF文档在制作的时候，有意将Unicode映射表删掉了，造成我们无法得知复制的字对应的是Unicode的哪一个字，所以无法复制粘贴文档中的文本。这是一个很简单，也很有效的文档反拷贝手段。&lt;/p&gt;

&lt;p&gt;为了解决这个问题，我写了一个软件&lt;a href="https://www.cnblogs.com/Charltsing/p/19733153/PDFontFixer" rel="noopener noreferrer"&gt;PDFontFixer&lt;/a&gt;，采用OCR识别PDF文档中的字体里面的每一个字形，得到对应的Unicode编码，再将这些编码做成ToUnicode映射表，保存到PDF文档的字体里。这样，我们就可以正常复制粘贴文本了。&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7e3u6ghqia0gyijbfby.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv7e3u6ghqia0gyijbfby.gif" alt=" " width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>pdf</category>
    </item>
    <item>
      <title>How to Losslessly Remove Watermarks from PDF Pages</title>
      <dc:creator>Charltsing</dc:creator>
      <pubDate>Mon, 09 Mar 2026 09:47:57 +0000</pubDate>
      <link>https://dev.to/charltsing/how-to-losslessly-remove-watermarks-from-pdf-pages-4615</link>
      <guid>https://dev.to/charltsing/how-to-losslessly-remove-watermarks-from-pdf-pages-4615</guid>
      <description>&lt;p&gt;人人都见过PDF文档页面中的水印，就像下面这样：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa260jruhuf45x9r2dxvf.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa260jruhuf45x9r2dxvf.PNG" alt=" " width="800" height="849"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;我们有很多工具可以去掉那些影响阅读的水印，最优秀的工具是Enfocus PitStop Pro，一个又大又昂贵的插件 ---- 但是它确实好使。&lt;/p&gt;

&lt;p&gt;问题是：所有的商业软件在处理水印的时候，都会重新格式化文档内容流（由类似PostScript语言的操作符构成）和文档结构数据，这就不可避免地改变了原始文档。有些时候，这种改变会影响文档的二次处理。&lt;/p&gt;

&lt;p&gt;那么，我们为什么不能从另一个角度思考水印的处理方式呢？&lt;/p&gt;

&lt;p&gt;需要给普通人解释一下，PDF格式是一个渲染文档格式，它不像Word那样保证储存的是明文文本。实际上，许多PDF文档是采用绘图的方式或者内部编码的方式来显示文本和图片的。因此，你不能简单地删除水印（就像在Word里面删除字符那样）。&lt;/p&gt;

&lt;p&gt;这里我们看一下PDF文档的实际存储数据，这里是内容流：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotp3qxa1et2dbtvihbaz.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotp3qxa1et2dbtvihbaz.PNG" alt=" " width="800" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;所以，你可能需要提前学习一下PDF文档&lt;a href="https://dev.to/iurii_rogulia/binary-pdf-modification-detection-how-it-works-and-where-it-fails-ph9"&gt;结构&lt;/a&gt;，以及页面内容流中的&lt;a href="https://dev.to/michael_lahr/why-is-pdf-so-hard-to-edit-3h3l"&gt;操作符&lt;/a&gt;含义（这不是本文的内容）。&lt;/p&gt;

&lt;p&gt;在这个PDF的内容流中，你会明显可看到 &lt;em&gt;/Artifact /Subtype/Watermark&lt;/em&gt; 这一行信息，这说明水印是以/Artifact储存的，如果我们能够在内容流中直接删除它，是不是就可以去掉水印呢？&lt;/p&gt;

&lt;p&gt;那么，问题来了，至今为止，我没有见到任何一个软件允许使用者随意编辑pdf文档中的内容流。原因很简单，这会破坏PDF文档的完整性。随意地编辑它们，会导致PDF文档损坏。因此，一直以来，处理水印都是专用工具的事情。&lt;/p&gt;

&lt;p&gt;我在接触PDF文档一段时间之后，开始思考如何通过简单地修改内容流来达到删除水印的目的。道理很简单，水印并不是PDF文档的必备内容，删掉它们不会影响文档的完整性。&lt;/p&gt;

&lt;p&gt;唯一面临的难点是，我得自己从头写一个软件，负责给用户展示内容流操作符，并有条件地允许使用者修改它们。&lt;/p&gt;

&lt;p&gt;所以，&lt;a href="https://github.com/Charltsing/oPDF" rel="noopener noreferrer"&gt;oPDF&lt;/a&gt;软件诞生了。这是个免费工具，不像商业软件那样又大又贵。&lt;/p&gt;

&lt;p&gt;oPDF v2.1可以：&lt;br&gt;
1、去除编辑权限，展平表单，去除页面交互，删除数字签名。&lt;br&gt;
2、可以任意修改文档页面内容流和资源内容流的指令集，可以改文本，改颜色，改位置，也就是说它可以修改页面任何内容，并不仅仅是去水印。&lt;br&gt;
3、可以通杀八类PDF水印，包括注释水印、文本水印、曲线水印、路径水印、痕迹水印、表单水印、图片水印、图案水印。&lt;/p&gt;

&lt;p&gt;oPDF 软件的工作原理是根据使用者的指令，删除或者替换PDF文档页面的内容流中的操作符。这就从理论上避免的文档结构的重构，也就是实现了无损处理。&lt;/p&gt;

&lt;p&gt;如果你有更多问题，可以看看教程（中文版）&lt;br&gt;
&lt;a href="https://zhuanlan.zhihu.com/p/1991825405808747927" rel="noopener noreferrer"&gt;Remove Text watermarks&lt;/a&gt;&lt;br&gt;
&lt;a href="https://zhuanlan.zhihu.com/p/1992482307941107092" rel="noopener noreferrer"&gt;Remove Image watermarks&lt;/a&gt;&lt;br&gt;
&lt;a href="https://zhuanlan.zhihu.com/p/1992485901910159711" rel="noopener noreferrer"&gt;Use wildcard characters&lt;/a&gt;&lt;br&gt;
&lt;a href="https://zhuanlan.zhihu.com/p/1994421106275267960" rel="noopener noreferrer"&gt;Remove Artifact watermarks&lt;/a&gt;&lt;br&gt;
&lt;a href="https://zhuanlan.zhihu.com/p/1995492413335180007" rel="noopener noreferrer"&gt;Remove Resource watermarks and Artifact Watermarks by serial number&lt;/a&gt;&lt;br&gt;
&lt;a href="https://zhuanlan.zhihu.com/p/1996631418231607699" rel="noopener noreferrer"&gt;Remove Annotation watermarks&lt;/a&gt;&lt;br&gt;
&lt;a href="https://zhuanlan.zhihu.com/p/2005208521139058108" rel="noopener noreferrer"&gt;Remove Curve watermarks (Color section)&lt;/a&gt;&lt;br&gt;
&lt;a href="https://zhuanlan.zhihu.com/p/2005713879133622924" rel="noopener noreferrer"&gt;Remove Text watermarks (location section)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stay tuned for more tutorials...&lt;/p&gt;

</description>
      <category>pdf</category>
    </item>
  </channel>
</rss>
