精华内容
下载资源
问答
  • 如何去除文件水印
    千次阅读
    2020-10-26 11:16:04

    参考链接:https://www.cnblogs.com/EdisonVan/p/9460101.html

    下面记录一下gojs去除水印的方法:

    在go.js中搜索关键字7eba17a4ca3b1a8346,将值替换成 function(){return true;},如:a.Jv=function(){return true;},可能前面并不一定是a.Jv=,但是不影响,把后面的值替换掉就可以了

    更多相关内容
  • 1.支持word,txt等文件转化成pdf 2.消除转化pdf水印
  • 去除PDF文件水印方法

    2011-11-08 17:30:29
    使用该方法我们就不用再为去不掉pdf上的水印而苦恼了!
  • 去水印工具新版.exe

    2020-05-24 10:41:39
    公司内部文件防护水印,文件打开乱码,无法打开等问题,去除文件水印乱码的小工具,使用方便,将文件拖入软件,点击脱除水印
  • Spire.Doc 去除版权水印

    2022-02-21 18:04:43
    Evaluation Warning: The document was created with Spire.Doc for .NET. 生成的word文档有这句话,如何去除。 保存使用document.SaveToFile
  • 使用itext开发包对pdf文件进行去水印操作,包括删除图片水印和文字水印。通过遍历pdf的contents对象和xobjects对象,进行对象删除,速度快,效率高
  • 去除电脑水印工具.rar

    2020-08-07 14:24:31
    win7-10去左下角水印工具,亲测可完美去除测试模式,水印等等
  • 针对的是网上下载的OpenCV 3.x with Python By Example 2nd Edition PDF文件,采用Python和PyPDF2编程,去除该PDF上的文字水印去除水印的方法随着采用的加水印的方法不同而不同,所采用的方法对于去除一些指定的...
  • 去水印工具

    2015-10-09 11:27:26
    非常好用的图片去水印工具,当然需要序列号,这里有一个:XCQF-NAYT-AACA-ATFA-XKVX-FAFK-QPAA-KPAA
  • 应用背景水印或前景图章 报告 PDF 指标、书签和元数据 添加/更新 PDF 书签或元数据 将文件附加到 PDF 页面或 PDF 文档 解压 PDF 附件 将 PDF 文档分成单页 解压缩和重新压缩页面流 修复损坏的 PDF(在可能的情况下)...
  • 适用于originPro 2018 b9.5.0.193,因为安装的就是这个版本,其他版本没试过,亲测可用去除DEMO水印。复制ok95.dll和ok95_64.dll两个文件到安装目录(本人;C:\Program Files\OriginLab\Origin2018),覆盖源文件。
  • 这里资源是已经去掉水印的压缩包文件,可通过解压后,覆盖本地已经下载下来的包文件内容即可。无需过多操作设置,可正常使用。
  • PDF文件JAVA去水印源码Muhimbi PDF Converter 在线服务 关于 这是一项基于 REST 的服务,可以轻松地将文档转换、合并、水印、保护和光学字符识别 (OCR) 添加到大多数编程语言、操作系统和开发平台。 此服务也可作为...
  • go.js 去水印,不再有丑陋的水印,完美!官方最新版本!!!go.js 去水印,不再有丑陋的水印,完美!官方最新版本
  • 使用Graphics和LockBits锁内存方式进行图片水印的添加和去掉操作
  • 2、批量水印去除:PDF标志移除器提供了方便的批处理模式,用户可以从PDF文件中删除任何类型的图像,可以清理标识类型、背景图像、页眉和页脚图像,或任何其他类型的嵌入图像。 3、嵌入你自己的水印:除了从PDF文件中...
  • OriginPro2018去除demo水印 ,直接将下载得到的文件替换安装目录下的文件即可
  • 需求需要对不同文件水印,例如:jpg,png,pdf,word 由于不同文件不同的方式,所以进行逐个功能开发 调研 图片文件(jpg,png,e.g.):通过ImageIO PDF:1.itextpdf 2.pdfbox Word:1.通过Free Spire for Doc 2....

    背景

    • 需求需要对不同文件加水印,例如:jpg,png,pdf,word
    • 由于不同文件不同的方式,所以进行逐个功能开发

    调研

    • 图片文件(jpg,png,e.g.):通过ImageIO
    • PDF:1.itextpdf 2.pdfbox
    • Word:1.通过Free Spire for Doc 2.apache poi

    分析

    对比

    1. 图片文件,最好选择就是通过ImageIO,ImageIO为Java的自带工具类javax.imageio.ImageIO
    2. PDF下
      1. itext官网url:https://itextpdf.com/en(付费)
      2. pdfbox官网url:https://pdfbox.apache.org/(开源)
    3. Word:
      1. Free Spire Doc For java官网:https://www.e-iceblue.cn/licensing/install-spirepdf-for-java-from-maven-repository.html (开源版本功能有限,所有功能必须使用付费版)
      2. apache poi 官网: https://poi.apache.org/ (免费)

    总结

    1. 图片文件加水印,通过ImageIO可以满足
    2. PDF文件加水印,由于itext为付费框架,所以选择开源框架pdfbox
    3. Word通过测试使用Free Spiredoc for java 开源版加完水印会在文件上生成一行字。而 apache poi对水印的操作只支持文字,最终用两者结合的方式来实现完整功能, 此方法受限很大,不支持wps生成的doc文件,部分旧版doc也不支持。

    框架使用

    ImageIO

    Api总览

    • 类名描述
      ImageIO一个类包含静态方便定位方法 ImageReaders和 ImageWriters,并进行简单的编码和解码。
      BufferedImageBufferedImage类描述了一个 Image与访问图像数据缓冲区。一个 BufferedImage是由一个 ColorModelRaster图像数据。在 RasterSampleModel数量和类型的乐队必须匹配的数量和类型的 ColorModel要求代表它的颜色和alpha分量。所有的 BufferedImage对象的左上角坐标(0, 0)。任何 Raster用来构建一个 BufferedImage必须有X = 0和迷你= 0。 这类依赖于数据的读取和Raster设置方法,并对ColorModel颜色表征方法。
      Graphics2D提供强大的绘图能力。Graphic2D类扩展了Graphic类提供几何更复杂的控制系统的坐标变换,色彩管理和文本布局。
      AlphaComposite实现基本的alpha合成相结合的源和目标的颜色来实现融合,图形和图像的透明度的影响规律
    • ImageIO的方法

      • Modifier and TypeMethod and Description
        static ImageInputStreamcreateImageInputStream(Object input) 返回一个 ImageInputStream将从给定的输入 Object
        static ImageOutputStreamcreateImageOutputStream(Object output) 返回一个 ImageOutputStream,将其输出到了 Object
        static FilegetCacheDirectory() 返回由 setCacheDirectory的当前值,或 null如果没有显式设置了。
        static ImageReadergetImageReader(ImageWriter writer) 返回一个 ImageReadercorresponding到给定的 ImageWriter,如果有一个,或 null如果插件,这 ImageWriter不指定相应的 ImageReader,或者给 ImageWriter没有注册。
        static Iterator<ImageReader>getImageReaders(Object input) 返回一个包含所有当前注册 ImageReaders Iterator声称能提供 Object解码,通常 ImageInputStream
        static Iterator<ImageReader>getImageReadersByFormatName(String formatName) 返回一个包含所有当前注册 Iterator ImageReaders声称能够解码的命名格式。
        static Iterator<ImageReader>getImageReadersByMIMEType(String MIMEType) 返回一个包含所有当前注册 Iterator ImageReaders声称能够解码文件与给定的MIME类型。
        static Iterator<ImageReader>getImageReadersBySuffix(String fileSuffix) 返回一个包含所有当前注册 Iterator ImageReaders声称能够解码文件的后缀。
        static Iterator<ImageTranscoder>getImageTranscoders(ImageReader reader, ImageWriter writer) 返回一个包含所有当前注册 ImageTranscoders Iterator声称能将给定的 ImageReaderImageWriter元数据之间。
        static ImageWritergetImageWriter(ImageReader reader) 返回一个 ImageWritercorresponding到给定的 ImageReader,如果有一个,或 null如果插件,这 ImageReader不指定相应的 ImageWriter,或者给 ImageReader没有注册。
        static Iterator<ImageWriter>getImageWriters(ImageTypeSpecifier type, String formatName) 返回一个包含所有当前注册 Iterator ImageWriters声称能够编码的图像(使用一个给定的布局 ImageTypeSpecifier指定)在给定的格式。
        static Iterator<ImageWriter>getImageWritersByFormatName(String formatName) 返回一个包含所有当前注册 Iterator ImageWriters声称能够编码的命名格式。
        static Iterator<ImageWriter>getImageWritersByMIMEType(String MIMEType) 返回一个包含所有当前注册 ImageWriters Iterator声称能与给定的MIME类型文件的编码。
        static Iterator<ImageWriter>getImageWritersBySuffix(String fileSuffix) 返回一个包含所有当前注册 ImageWriters Iterator声称能与给定的后缀文件编码。
        static String[]getReaderFileSuffixes() 返回 Strings列出所有与格式的当前注册读者理解相关的文件后缀数组。
        static String[]getReaderFormatNames() 返回 Strings列出所有的非正式格式名称注册读者理解数组的当前设置。
        static String[]getReaderMIMETypes() 返回 Strings列出所有的MIME类型注册读者了解当前设置的数组。
        static booleangetUseCache() 返回由 setUseCache的当前值,或 true如果没有显式设置了。
        static String[]getWriterFileSuffixes() 返回 Strings列出所有的格式由注册作家当前理解的关联文件后缀数组。
        static String[]getWriterFormatNames() 返回 Strings列出所有的非正式格式名称注册作家当前理解数组。
        static String[]getWriterMIMETypes() 返回 Strings列出所有的MIME类型注册作家当前理解数组。
        static BufferedImageread(File input) 返回一个 BufferedImage作为一个 ImageReader自动选择从当前注册提供 File解码结果。
        static BufferedImageread(ImageInputStream stream) 返回一个 BufferedImage作为一个 ImageReader自动选择从当前注册提供 ImageInputStream解码结果。
        static BufferedImageread(InputStream input) 返回一个 BufferedImage作为一个 ImageReader自动选择从当前注册提供 InputStream解码结果。
        static BufferedImageread(URL input) 返回一个 BufferedImage作为一个 ImageReader自动选择从当前注册提供 URL解码结果。
        static voidscanForPlugins() 在应用程序的类路径加载插件扫描,服务提供程序类,并注册一个服务提供商,例如每一个发现与 IIORegistry
        static voidsetCacheDirectory(File cacheDirectory) 设置要创建缓存文件的目录。
        static voidsetUseCache(boolean useCache) 设置一个指示是否基于磁盘的缓存文件应该创造 ImageInputStreams和 ImageOutputStreams时使用的国旗。
        static booleanwrite(RenderedImage im, String formatName, File output) 写一个图像使用任意 ImageWriter支持特定格式的一 File
        static booleanwrite(RenderedImage im, String formatName, ImageOutputStream output) 写一个图像使用任意 ImageWriter支持给格式的 ImageOutputStream
        static booleanwrite(RenderedImage im, String formatName, OutputStream output) 写一个图像使用任意 ImageWriter支持给格式的 OutputStream
    • BufferedImage方法

      • Modifier and TypeField and Description
        static intTYPE_3BYTE_BGR 代表8位RGB分量图像,对应一个Windows风格BGR颜色模型)与蓝色、绿色、红色3个字节存储。
        static intTYPE_4BYTE_ABGR 代表8位RGBA颜色成分的蓝色、绿色和红色的图像,存储在3字节和1字节的α。
        static intTYPE_4BYTE_ABGR_PRE 代表8位RGBA颜色成分的蓝色、绿色和红色的图像,存储在3字节和1字节的α。
        static intTYPE_BYTE_BINARY 表示一个不透明的字节填充的1,2,或4位图像。
        static intTYPE_BYTE_GRAY 表示一个无符号字节的灰度图像,无索引。
        static intTYPE_BYTE_INDEXED 表示一个索引字节图像。
        static intTYPE_CUSTOM 图像类型是不被识别的,所以它必须是一个自定义的图像。
        static intTYPE_INT_ARGB 代表8位RGBA颜色组件包装成整数像素的图像。
        static intTYPE_INT_ARGB_PRE 代表8位RGBA颜色组件包装成整数像素的图像。
        static intTYPE_INT_BGR 代表8位RGB分量图像,对应于Windows或Solaris式BGR颜色模型,用蓝色、绿色和红色包装成整数像素。
        static intTYPE_INT_RGB 代表8位RGB分量包装成整数像素的图像。
        static intTYPE_USHORT_555_RGB 代表5-5-5 RGB分量图像(五位红、五位绿色,五位蓝色)没有α。
        static intTYPE_USHORT_565_RGB 代表5-6-5 RGB分量图像(五位红,六位绿色,五位蓝色)没有α。
        static intTYPE_USHORT_GRAY 表示一个无符号的短灰度图像,非索引的。
    • Graphics2D

      • Graphic2D类提供强大的绘图能力。Graphic2D类扩展了Graphic类提供几何更复杂的控制系统的坐标变换,色彩管理和文本布局。

      • Java文档

        • 坐标空间
          所有坐标传递给 Graphics2D对象在一个独立于设备的坐标系统称为用户空间的规定,这是由应用程序使用。的 Graphics2D对象包含一个 AffineTransform对象作为其渲染状态的一部分,定义了如何转换坐标从用户空间到设备空间依赖于设备坐标。 
          在设备空间中的坐标通常是指单独的设备像素,并对准这些像素之间的无限薄的差距。一些Graphics2D对象可以用来捕捉渲染操作存储成一个图形文件对以后未知的物理分辨率的具体设备的播放。由于分辨率可能不知道,当绘制操作的Graphics2D Transform捕获,建立用户坐标系变换到一个虚拟的设备空间,接近目标设备预期的分辨率。进一步的转换可能需要被应用在播放时间,如果估计是不正确的。
          
          有些作业的渲染属性的对象出现在装置的空间,但是所有的Graphics2D方法把用户空间坐标。
          
          每一Graphics2D对象与目标定义在渲染发生相关。一个GraphicsConfiguration对象定义的渲染目标的特征,如像素格式和分辨率。相同的渲染目标是在一个Graphics2D对象的生活。
          
          创建一个Graphics2D对象时的GraphicsConfiguration指定的Graphics2D目标default transform(一Component或Image)。这个默认变换将用户空间坐标系统映射到屏幕和打印机设备的坐标,这样的原点映射到设备的目标区域的左上角,增加x坐标延伸到右边,增加Y坐标向下延伸。默认的缩放变换是这些设备的接近72的DPI设置为身份,如屏幕设备。默认变换的缩放设置为每平方英寸约72个用户空间坐标,用于高分辨率设备,如打印机。图像缓冲区,默认的变换是Identity变换。
          
          绘制过程
          渲染过程可以分成四个阶段,由 Graphics2D渲染属性控制。渲染器可以优化这些步骤,通过缓存未来呼吁的结果,被倒塌的多个虚拟成一个单一的操作步骤,或通过识别各种属性作为常见的简单的情况,可以通过修改操作的其他部分消除。 
          渲染过程中的步骤是:
          
          决定要渲染什么。 
          约束的绘制操作的当前Clip,Clip是由用户空间的一个Shape指定是用Graphics和Graphics2D各种剪辑手法的程序控制。这个空用户卡转化装置的空间由目前的Transform结合空夹持器,这是由Windows和设备程度的可见性定义。用户的夹具和装置夹的组合定义了空复合夹,这决定了最终的裁剪区域。用户剪辑不被渲染系统修改,以反映所得到的复合剪辑。 
          确定要渲染的颜色。 
          应用颜色到目的地绘制表面采用目前Composite属性在Graphics2D语境。 
          
          三种绘制作业,随着他们的每一个特定的渲染过程的细节是: 
          Shape operations 
          如果操作是一个draw(Shape)操作,然后createStrokedShape法在Graphics2D上下文的当前Stroke属性是用来构建一个新的Shape对象包含指定的Shape概述。 
          是的Shape从用户空间转换到设备空间使用当前Transform在Graphics2D语境。 
          该Shape轮廓用Shape的getPathIterator提取方法,它返回一个对象,PathIterator迭代的Shape沿边界。 
          如果Graphics2D对象不能处理的曲线段,PathIterator对象返回就可以打电话Shape交替getPathIterator方法,并将Shape。 
          在Graphics2D上下文的当前Paint查询一个PaintContext,指定颜色在设备空间渲染。 
          Text operations 
          以下步骤用于确定需要渲染的结果String符号集: 
          如果参数是一个String,然后在Graphics2D上下文的当前Font要求转换为Unicode字符在String为一组符号表示什么的基本布局和整形算法实现的字体。 
          如果参数是一个AttributedCharacterIterator,迭代器要求将自己一TextLayout使用嵌入式字体属性。实现更复杂的TextLayout字形布局算法进行Unicode双向布局自动调整为不同的写作方向,多种字体。 
          如果参数是一个GlyphVector,然后GlyphVector对象已经包含合适的字体特定的字形码为每个符号的位置明确的坐标。 
          目前Font查询获得的指示符号概述。这些大纲被视为在用户空间中的形状相对于每一个字形的位置,在步骤1中确定。 
          字符轮廓填充如上下Shape operations。 
          目前Paint查询一个PaintContext,指定颜色在设备空间渲染。 
          Image Operations 
          感兴趣区域是由原Image包围盒的定义。这个边界框在图像空间中指定的,这是Image对象的局部坐标系统。 
          如果一个AffineTransform传递的drawImage(Image, AffineTransform, ImageObserver),AffineTransform用于将包围盒从图像空间到用户空间。如果不提供AffineTransform,包围盒作为如果它已经在用户空间。 
          的源Image包围盒是从用户空间转化装置的空间使用当前Transform。请注意,转换的包围盒的结果并不一定会导致在设备空间中的矩形区域。 
          的Image对象决定什么颜色渲染,取样根据源到目的地的坐标映射指定的电流Transform和可选的图像变换。 
          默认的渲染属性
          默认值为 Graphics2D渲染属性: 
          nullpaint 
          Component的颜色。 
          nullfont 
          该 Component的 Font。 
          nullstroke 
          方笔线宽1,没有浮华,斜切段连接和方形端盖。 
          nulltransform 
          对 Component的 GraphicsConfiguration的 getDefaultTransform。 
          nullcomposite 
          的 AlphaComposite.SRC_OVER规则。 
          nullclip 
          没有渲染 Clip,输出的是夹到 Component。 
          渲染的兼容性问题
          JDK(TM)1.1绘制模型是基于像素化模型,指定坐标是无限薄,躺在之间的像素。使用一一个像素宽的笔,填充的像素的下方,并在路径上的锚点的右侧进行绘图操作。JDK 1.1绘制模型与大多数平台的渲染器,需要解决整数坐标离散的笔,必须完全落在指定的像素数现有类的能力相一致。 
          java 2D(TM)(java(TM)2平台)API支持抗锯齿渲染。一个宽度为一个像素的笔不需要完全落在像素N,而不是像素n + 1。笔可以部分落在两个像素上。它是没有必要选择一个广泛的笔的偏置方向,因为沿笔遍历边缘发生的混合,使笔的子像素位置的用户可见。另一方面,当抗锯齿设置KEY_ANTIALIASING暗示关键的VALUE_ANTIALIAS_OFF提示值关闭,渲染器可能需要申请一个偏置来确定哪些像素修改当笔跨界像素边界,如当它是画在设备空间的整数坐标。虽然一个抗锯齿渲染能力使渲染的模型指定为钢笔的偏见不再是必要的,它是理想的抗锯齿和非抗锯齿渲染执行同样的常见情况绘制一个像素宽的水平和垂直线的屏幕上。确保打开抗锯齿设置KEY_ANTIALIASING提示键VALUE_ANTIALIAS_ON不会引起这些线突然变得宽两倍,一半是不透明的,是最为理想的模型指定一个这样的线路路径使他们完全覆盖一组特定的像素来帮助他们增加脆度。
          
          java JDK 1.1绘制2D API保持行为的相容性,使得传统业务和现有的渲染行为不变的情况下,java 2D API。传统的方法是定义映射到一般draw和fill方法,这清楚地表明,如何Graphics2D延伸Graphics基于Stroke和Transform属性和渲染提示设置。定义执行相同的默认属性设置。例如,默认Stroke是BasicStroke宽度在1和没有闯劲、默认变换屏幕绘图是一个恒等变换。
          
          以下两个规则提供可预测的渲染行为是否锯齿或锯齿被使用。
          
          设备坐标系定义为设备像素之间,避免任何不一致的结果之间的锯齿和抗锯齿渲染。如果坐标被定义为在一个像素的中心,一些覆盖的形状,如一个矩形,只会被覆盖的一半。与处理、半覆盖的像素将被呈现在形状或外部形状。抗锯齿渲染,对塑造整个边缘像素会有一半。另一方面,由于坐标定义为像素之间,形状像一个矩形将没有半覆盖的像素,是否使用抗锯齿渲染。 
          线和路径抚摸使用BasicStroke对象可能是“标准化”提供了一致的渲染定位时,在各点上的冲和是否绘制锯齿或锯齿渲染。这种过程是由KEY_STROKE_CONTROL提示控制。没有指定确切的归一化算法,但这种正常化的目标是确保线条的呈现一致的外观无论怎样它们落在像素网格和促进反锯齿模式更坚实的水平线和垂直线使他们像他们的非抗锯齿的同行更密切。一个典型的归一化步骤可能促进抗锯齿线端点像素中心降低掺量或调整非抗锯齿线的亚像素定位使浮点线宽度轮偶数或奇数像素数相等的可能性。这个过程可以移动端点高达半个像素(通常是沿两个轴的正无穷大),以促进这些一致的结果。 
          一般传统方法的以下定义执行相同的默认属性设置下的以前指定的行为:
          
          对于fill操作,包括fillRect,fillRoundRect,fillOval,fillArc,fillPolygon,和clearRect,fill现在可以被称为理想的Shape。例如,当填充矩形:
          填充(新的矩形(X,Y,W,H));
          叫做。
          
          同样,对于绘制操作,包括drawLine,drawRect,drawRoundRect,drawOval,drawArc,drawPolyline,和drawPolygon,draw现在可以被称为理想的Shape。例如,当绘制一个矩形:
          绘制(新的矩形(X,Y,W,H));
          叫做。
          
          在Graphics类,谓其行为在Graphics2D上下文的当前Stroke和Paint对象的drawLine和fillRect方法上实现了draw3DRect和fill3DRect方法。这类重写这些实现版本使用当前Color完全覆盖当前Paint和使用fillRect描述完全相同的行为,原有的方法无论当前Stroke设置。 
          的 Graphics类只定义 setColor方法控制颜色画。由于java 2D API扩展 Color对象实施新的 Paint接口,现有的 setColor方法现在是一个用于设置当前 Paint属性到一个 Color对象方便的方法。 setColor(c)相当于 setPaint(c)。 
          的Graphics类定义了两个方法控制颜色如何应用到目的地。
          
          的setPaintMode方法是设置默认Composite方便的方法实现的,相当于setComposite(new AlphaComposite.SrcOver)。 
          的setXORMode(Color xorcolor)方法的实施作为一种方便的方法,设置了一个特殊的Composite对象,忽略了Alpha组件源颜色和目标颜色设置值:
          dstpixel =(PixelOf(srccolor)^ PixelOf(xorcolor)^ dstpixel);
          
          
      • 方法

        • Modifier and TypeMethod and Description
          abstract voidaddRenderingHints(Map<?,?> hints) 设置渲染算法的任意数量的首选项的值。
          abstract voidclip(Shape s) 与目前的 Clip与指定的 Shape室内设置产生的交叉 Clip
          abstract voiddraw(Shape s) 下一 Shape使用当前 Graphics2D语境设置的轮廓。
          voiddraw3DRect(int x, int y, int width, int height, boolean raised) 绘制指定矩形的三维突出显示的轮廓。
          abstract voiddrawGlyphVector(GlyphVector g, float x, float y) 使文本的指定 GlyphVector使用 Graphics2D语境的渲染属性。
          abstract voiddrawImage(BufferedImage img, BufferedImageOp op, int x, int y) 呈现 BufferedImage,与 BufferedImageOp过滤。
          abstract booleandrawImage(Image img, AffineTransform xform, ImageObserver obs) 渲染一个图像,在绘制之前将图像空间的一个变换转换成用户空间。
          abstract voiddrawRenderableImage(RenderableImage img, AffineTransform xform) 呈现 RenderableImage,应用变换从图像空间到用户空间的画前。
          abstract voiddrawRenderedImage(RenderedImage img, AffineTransform xform) 呈现 RenderedImage,应用变换从图像空间到用户空间的画前。
          abstract voiddrawString(AttributedCharacterIterator iterator, float x, float y) 使指定的迭代器将其属性按照 TextAttribute类的规范文本。
          abstract voiddrawString(AttributedCharacterIterator iterator, int x, int y) 使指定的迭代器将其属性按照 TextAttribute类的规范文本。
          abstract voiddrawString(String str, float x, float y) 将由指定的 String指定的文本,使用当前的文本属性状态的 Graphics2D语境。
          abstract voiddrawString(String str, int x, int y) 使指定的 String文本,使用当前的文本属性状态的 Graphics2D语境。
          abstract voidfill(Shape s) 填补了一 Shape使用的 Graphics2D语境设置的内部。
          voidfill3DRect(int x, int y, int width, int height, boolean raised) 画一个充满当前颜色的三维高亮矩形。
          abstract ColorgetBackground() 返回用于清除区域的背景色。
          abstract CompositegetComposite() 在返回的 Graphics2D上下文的当前 Composite
          abstract GraphicsConfigurationgetDeviceConfiguration() 返回与此相关的设备配置 Graphics2D
          abstract FontRenderContextgetFontRenderContext() 在这 Graphics2D上下文得到的 Font渲染上下文。
          abstract PaintgetPaint() 返回的 Graphics2D上下文的当前 Paint
          abstract ObjectgetRenderingHint(RenderingHints.Key hintKey) 返回一个单独的渲染算法的偏好值。
          abstract RenderingHintsgetRenderingHints() 获取渲染算法的首选项。
          abstract StrokegetStroke() 在返回的 Graphics2D上下文的当前 Stroke
          abstract AffineTransformgetTransform() 返回一个在 Graphics2D上下文的当前 Transform
          abstract booleanhit(Rectangle rect, Shape s, boolean onStroke) 检查是否 Shape相交的指定 Rectangle,这是设备空间。
          abstract voidrotate(double theta) 将当前 Graphics2D Transform与旋转变换。
          abstract voidrotate(double theta, double x, double y) 将当前 Graphics2D Transform与翻译旋转变换。
          abstract voidscale(double sx, double sy) 将当前 Graphics2D Transform与尺度转换以后呈现大小按指定的比例因子缩放相对于以前。
          abstract voidsetBackground(Color color) 设置为 Graphics2D上下文的背景颜色。
          abstract voidsetComposite(Composite comp) 设置为 Graphics2D语境 Composite
          abstract voidsetPaint(Paint paint) 设置为 Graphics2D语境 Paint属性。
          abstract voidsetRenderingHint(RenderingHints.Key hintKey, Object hintValue) 设置一个单独的渲染算法的偏好值。
          abstract voidsetRenderingHints(Map<?,?> hints) 取代所有偏好值与指定的 hints渲染算法。
          abstract voidsetStroke(Stroke s) 设置为 Graphics2D语境 Stroke
          abstract voidsetTransform(AffineTransform Tx) 覆盖在 Graphics2D语境的变换。
          abstract voidshear(double shx, double shy) 将当前 Graphics2D Transform与剪切变换。
          abstract voidtransform(AffineTransform Tx) 在这 Graphics2D组成的 Transform AffineTransform对象根据规则上指定的首次应用。
          abstract voidtranslate(double tx, double ty) 将当前 Graphics2D Transform与平移变换。
          abstract voidtranslate(int x, int y) 翻译语境的 Graphics2D起源点(nullx, nully)在当前坐标系统。

    基本使用

    1.图片的输入输出
    1. 读取图片

      • BufferedImage read = ImageIO.read(new FileInputStream(imgPath));
        
    2. 保存图片

      •     //保存图片
            File file = new File("D:\\image.jpg");
            ImageIO.write( new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB), "jpg", file);
        
    3. 将一幅图片输入输出:

      •     public static void main(String[] args) {
                try {
                    //将图片读入内存
                    String imgPath = "D:\\image.jpg";
                    BufferedImage read = ImageIO.read(new FileInputStream(imgPath));
                    
                    //保存图片
                    File file = new File("D:\\imagesave.jpg");
                    ImageIO.write( new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB), "jpg", file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
    2、创建BufferedImage对象
    •     /**
           * 
           * @param width e.g. 20
           * @param height e.g. 40
           * @param imageType e.g. BufferedImage.TYPE_BYTE_GRAY
           * @return
           */
          public BufferedImage createdBufferedImage(Integer width,Integer height,Integer imageType) {
              //指定宽高、创建带灰色的对象:
              BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_GRAY);
              //创建一个不带透明色的对象
              BufferedImage bufferedImage1 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
              //创建一个带透明色的对象
              BufferedImage bufferedImage2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
              return null;
          }
      
    3、图片裁剪
    •     /**
           * BufferedImage 功能介绍
           */
          public static void imageIOApi() {
              try {
                  BufferedImage bufferedImage = ImageIO.read(new File("D:/watermark.jpg"));
                  //获取图片的宽高
                  int width = bufferedImage.getWidth();
                  int height = bufferedImage.getHeight();
                  //图片裁剪
                  BufferedImage subimage = bufferedImage.getSubimage(0, 0, 10, 10);
                  //创建画笔对象
                  Graphics2D graphics = bufferedImage.createGraphics();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
    4、画一个黑色正方形
    •     @Test
          public void drawImage() {
              try {
                  //指定宽高、创建带灰色的对象:
                  BufferedImage bufferedImage = new BufferedImage(200, 200, BufferedImage.TYPE_USHORT_555_RGB);
                  Graphics2D graphics = bufferedImage.createGraphics();
                  graphics.drawImage(bufferedImage,200,200,null);
                  ImageIO.write(bufferedImage, "jpg", new File("D:\\test.jpg"));
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
    5、设置透明度
    •     @Test
          public void setAlphaComposite() {
              try {
                  //源文件
                  BufferedImage original = ImageIO.read(new FileInputStream("D:\\original.jpg"));
                  //黑框
                  BufferedImage bufferedImage = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
                  //源文件上创建画笔 Graphic2D
                  Graphics2D graphics = original.createGraphics();
                  //设置透明度
                  graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.3f));
      
                  graphics.drawImage(bufferedImage,200,200,null);
                  ImageIO.write(original, "jpg", new File("D:\\test.jpg"));
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
    6、旋转图片
    •     @Test
          public void rotate() {
              try {
                  BufferedImage read = ImageIO.read(new FileInputStream("D:\\original.jpg"));
                  BufferedImage bufferedImage = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
                  Graphics2D graphics2D = read.createGraphics();
                  graphics2D.rotate(50d);
                  graphics2D.drawImage(bufferedImage, 200, 200, null);
                  ImageIO.write(read, "jpg", new File("D:\\test.jpg"));
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
    7、控制图片位置
    •     @Test
          public void rotate() {
              try {
                  BufferedImage read = ImageIO.read(new FileInputStream("D:\\original.jpg"));
                  BufferedImage bufferedImage = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB);
                  Graphics2D graphics2D = read.createGraphics();
                  graphics2D.rotate(50d);
                  //控制图片位置
                  graphics2D.drawImage(bufferedImage, 10, 10, null);
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
    8、通过Graphic2D画一条直线
    •     /**
           * 在(3,3)与(50,50)之间画一条直线
           */
          @Test
          public  void graphics2DApi() {
              try {
                  BufferedImage read = ImageIO.read(new FileInputStream("D:\\image.jpg"));
                  Graphics2D graphics = read.createGraphics();
                  graphics.setColor(Color.red);
                  //在窗口画一条直线
                  graphics.drawLine(3,3,50,50);
                  ImageIO.write(read, "jpg",new File("D:\\line.jpg"));
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      
    9、应用FontMetrics精确定位
    • 	@Test
          public void fontMetrics() {
              try {
                  String s1 = "Hello,Java World!";
                  BufferedImage read = ImageIO.read(new FileInputStream("D:\\test.jpg"));
                  Graphics2D graphics = read.createGraphics();
                  graphics.setColor(Color.red);
                  graphics.setBackground(new Color(0,250,0));
                  Font font = new Font("Arial", Font.BOLD, 18);
                  graphics.setFont(font);
      
                  FontMetrics fontMetrics = graphics.getFontMetrics(font);
                  int height = fontMetrics.getHeight();
                  int widths = fontMetrics.stringWidth(s1);
                  int posx = 50; 
                  int posy = 50;
                  graphics.drawString(s1, posx, posy);
                  graphics.drawString("I Will come in.",posx+widths,posy+height);
      
                  ImageIO.write(read, "jpg", new File("D:\\test1.jpg"));
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      

    pdfBox

    概述

    • Apache PDFBox是一个开源Java库,支持PDF文档的开发和转换。 在本教程中,我们将学习如何使用PDFBox开发可以创建,转换和操作PDF文档的Java程序。
    PDFBox的功能

    以下是PDFBox的显着特征 -

    • Extract Text - 使用PDFBox,您可以从PDF文件中提取Unicode文本。
    • Split & Merge - 使用PDFBox,您可以将单个PDF文件分成多个文件,并将它们合并为一个文件。
    • Fill Forms - 使用PDFBox,您可以在文档中填写表单数据。
    • Print - 使用PDFBox,您可以使用标准Java打印API打印PDF文件。
    • Save as Image - 使用PDFBox,您可以将PDF保存为图像文件,如PNG或JPEG。
    • Create PDFs - 使用PDFBox,您可以通过创建Java程序创建新的PDF文件,还可以包含图像和字体。
    • Signing - 使用PDFBox,您可以将数字签名添加到PDF文件。
    PDFBox的应用

    以下是PDFBox的应用 -

    • Apache Nutch - Apache Nutch是一个开源的网络搜索软件。 它建立在Apache Lucene的基础上,添加了特定于Web的内容,例如爬虫,链接图数据库,HTML和其他文档格式的解析器等。
    • Apache Tika - Apache Tika是一个工具包,用于使用现有的解析器库从各种文档中检测和提取元数据和结构化文本内容。
    PDFBox的组件

    以下是PDFBox的四个主要组成部分 -

    • PDFBox - 这是PDFBox的主要部分。 它包含与内容提取和操作相关的类和接口。
    • FontBox - 它包含与font相关的类和接口,使用这些类我们可以修改PDF文档的文本字体。
    • XmpBox - 包含处理XMP元数据的类和接口。
    • Preflight - 此组件用于根据PDF/A-1b标准验证PDF文件。

    环境与安装

    安装PDFBox
    1. 通过maven方式安装

      • <dependencies>  
           <dependency> 
              <groupId>org.apache.pdfbox</groupId> 
              <artifactId>pdfbox</artifactId> 
              <version>2.0.1</version> 
           </dependency>   
           <dependency> 
              <groupId>org.apache.pdfbox</groupId> 
              <artifactId>fontbox</artifactId> 
              <version>2.0.0</version> 
           </dependency>
           <dependency>  
              <groupId>org.apache.pdfbox</groupId> 
              <artifactId>jempbox</artifactId> 
              <version>1.8.11</version> 
           </dependency> 
           <dependency>
              <groupId>org.apache.pdfbox</groupId> 
              <artifactId>xmpbox</artifactId> 
              <version>2.0.0</version> 
           </dependency> 
           <dependency> 
              <groupId>org.apache.pdfbox</groupId> 
              <artifactId>preflight</artifactId> 
              <version>2.0.0</version> 
           </dependency> 
           <dependency> 
              <groupId>org.apache.pdfbox</groupId> 
              <artifactId>pdfbox-tools</artifactId> 
              <version>2.0.0</version> 
           </dependency>
        </dependencies>
        

    基本使用

    创建PDF文档
    • 可以通过实例化PDFDocument类来创建空PDF文档。可以使用Save()方法保存所需的位置。

    • 代码

      •     /**
             * 创建空PDF文档
             */
            @Test
            public void pdfBox() {
                try {
                    //第一步:创建一个空文档
                    PDDocument document = new PDDocument();
                    //第二步:保存文档
                    document.save("D:\\test.pdf");
                    //第三步:关闭文档
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
    添加页面
    • 可以通过实例化PDPage类创建一个空页面,并使用PDDocument类的**addPage()**方法将其添加到PDF文档中。

    • 代码

      •     /**
             * 添加页面到PDF文档
             */
            @Test
            public void addingPages() {
                try {
                    //第一步:打开一个文档
                    PDDocument document = PDDocument.load(new FileInputStream("D:\\test.pdf"));
                    for (int i = 0; i < 10; i++) {
                        //第二步:创建空白页面
                        PDPage pdPage = new PDPage();
                        //第三步:向文档添加页面
                        document.addPage(pdPage);
                    }
                    //第四步:保存文档
                    document.save("D:\\test2.pdf");
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
    加载文档
    • PDDocument类的**load()**方法用于加载现有PDF文档。 按照以下步骤加载现有PDF文档。

    • 代码

      •     
            @Test
            public void loadDoc() {
                try {
                    //加载一个已存在的pdf文档
                    PDDocument document = PDDocument.load(new File("D:\\test2.pdf"));
                    //向文档添加一个新的页面
                    document.addPage(new PDPage());
                    //保存文档
                    document.save("D:\\test3.pdf");
                    //关闭文档
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
    删除页面
    • 您可以使用PDDocument类的**removePage()**方法从现有PDF文档中删除页面。

    • 代码

      • @Test
        public void removePage(){
            try {
                //加载一个现有文档
                PDDocument document = PDDocument.load(new FileInputStream("D:\\test3.pdf"));
                int numberOfPages = document.getNumberOfPages();
                System.out.println("PDF pages :"+ numberOfPages);
                //删除第二页, 索引为1 
                document.removePage(1);
        
                System.out.println("After Delete, PDF Page:"+document.getNumberOfPages());
                //保存文档
                document.save(new FileOutputStream("D:\\test4.pdf"));
                //关闭文档
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        
    插入图像
    • 可以分别使用PDImageXObjectPDPageContentStream类的**createFromFile()drawImage()**方法将图像插入PDF文档。

    • 代码

      •     
            @Test
            public void insertImage() {
                try {
                    //加载现有文档
                    PDDocument document = PDDocument.load(new FileInputStream(new File("D:\\test.pdf")));
                    document.addPage(new PDPage());
                    //检索页面
                    PDPage page = document.getPage(0);
                    //创建PDImageXObject对象
                    PDImageXObject imageXObject =  PDImageXObject.createFromFile("D:\\image.jpg", document);
                    //准备内容流
                    PDPageContentStream contentStream = new PDPageContentStream(document, page);
                    //在PDF文档中添加图像
                    contentStream.drawImage(imageXObject,70,250);
                    //关闭contentStream
                    contentStream.close();
                    //保存文件
                    document.save("D:\\inertImage.pdf");
                    //关闭文档
                    document.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        
    设置图像透明度
    • 通过PDExtendedGraphicsState的setNonStrokingAlphaConstant设置透明度

    • 代码

      •     @Test
            public void alphaSource() {
                try {
                    PDDocument document = new PDDocument();
                    document.addPage(new PDPage());
                    //检索页面
                    PDPage page = document.getPage(0);
                    //创建PDImageXObject对象
                    PDImageXObject imageXObject =  PDImageXObject.createFromFile("D:\\爱莎1.jpg", document);
                    //准备内容流
                    PDPageContentStream contentStream = new PDPageContentStream(document, page);
                    PDExtendedGraphicsState pdExtendedGraphicsState = new PDExtendedGraphicsState();
                    //透明度
                    pdExtendedGraphicsState.setNonStrokingAlphaConstant(0.5f);
                    pdExtendedGraphicsState.setAlphaSourceFlag(true);
                    pdExtendedGraphicsState.getCOSObject().setItem(COSName.BM,COSName.MULTIPLY);
                    contentStream.setGraphicsStateParameters(pdExtendedGraphicsState);
                    //在PDF文档中添加图像
                    contentStream.drawImage(imageXObject,70,250);
                    //关闭contentStream
                    contentStream.close();
                    //保存文件
                    document.save("D:\\inertImage.pdf");
                    //关闭文档
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        
    旋转图片
    • 通过Matrix对象,document.transform(maxtrix)来旋转图片

    • 代码

      • @Test
        public void rotate() {
            try {
                PDDocument document = new PDDocument();
                document.addPage(new PDPage());
                //检索页面
                PDPage page = document.getPage(0);
                //创建PDImageXObject对象
                PDImageXObject imageXObject =  PDImageXObject.createFromFile("D:\\爱莎1.jpg", document);
                //准备内容流
                PDPageContentStream contentStream = new PDPageContentStream(document, page);
                PDExtendedGraphicsState pdExtendedGraphicsState = new PDExtendedGraphicsState();
                //透明度
                pdExtendedGraphicsState.setNonStrokingAlphaConstant(0.5f);
                pdExtendedGraphicsState.setAlphaSourceFlag(true);
                pdExtendedGraphicsState.getCOSObject().setItem(COSName.BM,COSName.MULTIPLY);
                contentStream.setGraphicsStateParameters(pdExtendedGraphicsState);
                //旋转
                Matrix matrix = new Matrix();
                matrix.rotate(Math.toRadians(50));
                contentStream.transform(matrix);
                //在PDF文档中添加图像
                contentStream.drawImage(imageXObject,0,0);
                //关闭contentStream
                contentStream.close();
                //保存文件
                document.save("D:\\inertImage.pdf");
                //关闭文档
                document.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
    设置图片位置
    • 通过contentStream.drawImage(image,100,200)

    • 代码

      •     
            @Test
            public void insertImage() {
                try {
                    //加载现有文档
                    PDDocument document = PDDocument.load(new FileInputStream(new File("D:\\test.pdf")));
                    document.addPage(new PDPage());
                    //检索页面
                    PDPage page = document.getPage(0);
                    //创建PDImageXObject对象
                    PDImageXObject imageXObject =  PDImageXObject.createFromFile("D:\\爱莎1.jpg", document);
                    //准备内容流
                    PDPageContentStream contentStream = new PDPageContentStream(document, page);
                    //在PDF文档中添加图像
                    contentStream.drawImage(imageXObject,70,250);
                    //关闭contentStream
                    contentStream.close();
                    //保存文件
                    document.save("D:\\inertImage.pdf");
                    //关闭文档
                    document.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        

    Free Spiredoc for java

    概述

    • 官网api:https://www.e-iceblue.cn/spiredocforjava/spire-doc-for-java-program-guide-content.html

    安装

    • maven的pom

    • 先要配置repository

      • <repositories>
            <repository>
                <id>com.e-iceblue</id>
                <name>e-iceblue</name>
                <url> https://repo.e-iceblue.com/nexus/content/groups/public/</url>
            </repository>
        </repositories>
        
    • pom的dependency

      •     <dependency>
                <groupId>e-iceblue</groupId>
                <artifactId>spire.doc</artifactId>
                <version>4.12.1</version>
            </dependency>
        

    基本使用

    创建文档
    • Spire.Doc for Java提供的 Document类 可用于新建Word文档或加载现有的Word文件进行编辑。Word内容结构由Section节和Paragraph段落组成,向文档中添加节和段落时,分别使用 Document.addSetion() 方法和 Section.addParagraph() 方法。本次代码中将演示如何创建包含多个段落的Word文档。

    • 下表中列出了代码中使用到的核心类:

      • 解释
        Document表示文档模型
        Section表示文档模型中的节
        Paragraph表示文档模型中的段落
        ParagraphStyle表示文档中的段落样式,如段落的字体格式、对齐方式、段首缩进以及段落间距等
    • import com.spire.doc.*;
      import com.spire.doc.documents.HorizontalAlignment;
      import com.spire.doc.documents.Paragraph;
      import com.spire.doc.documents.ParagraphStyle;
      
      import java.awt.*;
      
      public class CreateWordDocument {
          public static void main(String[] args){
              //创建Word文档
              Document document = new Document();
      
              //添加一个section
              Section section = document.addSection();
      
              //添加三个段落至section
              Paragraph para1 = section.addParagraph();
              para1.appendText("滕王阁序");
      
              Paragraph para2 = section.addParagraph();
              para2.appendText("豫章故郡,洪都新府。星分翼轸,地接衡庐。襟三江而带五湖,控蛮荆而引瓯越。"+
                              "物华天宝,龙光射牛斗之墟;人杰地灵,徐孺下陈蕃之榻。雄州雾列,俊采星驰。台隍枕夷夏之交,宾主尽东南之美。"+
                              "都督阎公之雅望,棨戟遥临;宇文新州之懿范,襜帷暂驻。十旬休假,胜友如云;千里逢迎,高朋满座。"+
                              "腾蛟起凤,孟学士之词宗;紫电青霜,王将军之武库。家君作宰,路出名区;童子何知,躬逢胜饯。");
      
              Paragraph para3 = section.addParagraph();
              para3.appendText("时维九月,序属三秋。潦水尽而寒潭清,烟光凝而暮山紫。俨骖騑于上路,访风景于崇阿;临帝子之长洲,得天人之旧馆。"+
                              "层峦耸翠,上出重霄;飞阁流丹,下临无地。鹤汀凫渚,穷岛屿之萦回;桂殿兰宫,即冈峦之体势。");
      
              //将第一段作为标题,设置标题格式
              ParagraphStyle style1 = new ParagraphStyle(document);
              style1.setName("titleStyle");
              style1.getCharacterFormat().setBold(true);
              style1.getCharacterFormat().setTextColor(Color.BLUE);
              style1.getCharacterFormat().setFontName("宋体");
              style1.getCharacterFormat().setFontSize(12f);
              document.getStyles().add(style1);
              para1.applyStyle("titleStyle");
      
              //设置其余两个段落的格式
              ParagraphStyle style2 = new ParagraphStyle(document);
              style2.setName("paraStyle");
              style2.getCharacterFormat().setFontName("宋体");
              style2.getCharacterFormat().setFontSize(11f);
              document.getStyles().add(style2);
              para2.applyStyle("paraStyle");
              para3.applyStyle("paraStyle");
      
              //设置第一个段落的对齐方式
              para1.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
      
              //设置第二段和第三段的段首缩进
              para2.getFormat().setFirstLineIndent(25f);
              para3.getFormat().setFirstLineIndent(25f);
      
              //设置第一段和第二段的段后间距
              para1.getFormat().setAfterSpacing(15f);
              para2.getFormat().setAfterSpacing(10f);
      
              //保存文档
              document.saveToFile("Output.docx", FileFormat.Docx);
          }
      }
      
    读取和删除 Word 文档属性
    • 加载文档

      •     Document document = new Document();
            document.loadFromFile("D:\\text.docx");
        
    添加文字水印
    •     @Test
          public void insertTextWaterMark() {
              Document document = new Document();
              document.loadFromFile("D:\\text.docx");
              
              //开始插入水印
              TextWatermark textWatermark = new TextWatermark();
              textWatermark.setText("内部使用");
              textWatermark.setFontSize(40);
              textWatermark.setColor(Color.RED);
              textWatermark.setLayout(WatermarkLayout.Diagonal);
              document.getSections().get(0).getDocument().setWatermark(textWatermark);
              
              //保存文件
              document.saveToFile("D:\\text1.docx");
          }
      
    添加图片水印
    •    
          @Test
          public void addImageWatermark() throws IOException {
      
              //加载Word文档
              Document document = new Document();
              document.loadFromFile("D:\\text.docx");
      
              //创建PictureWatermark实例
              PictureWatermark picture = new PictureWatermark();
              ClassPathResource classPathResource = new ClassPathResource(WATER_MARK_PATH);
      
              //设置水印图片属性
              picture.setPicture(new FileInputStream(classPathResource.getFile()));
              picture.setScaling(150);
              picture.isWashout(false);
      
              //添加水印图片到文档
              document.setWatermark(picture);
      
              //保存结果文件
              document.saveToFile("D:\\text1.docx", FileFormat.Docx );
          }
      

    Apache POI

    • 针对POI是在操作word文档时,对Free spire.doc for java框架的补充,由于Free spire使用的是开源版,所以在生成文件后会有
      • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qm3SJtg0-1646878066806)(D:\cita\doc\Rivtrust自研\知识库\Java加水印\pic\spire.png)]
    • 针对上面问题操作是,在使用spire时,在文档首页新增一个空白页,然后通过Apache POI删除空白页。【这样操作的原因时,上面的文字时spire在通过document.saveToFile()方法中添加的】

    基本操作

    加载文档
    • ByteArrayInputStream swapStream = new ByteArrayInputStream(spire.toByteArray());
      XWPFDocument document1 = new XWPFDocument(swapStream);
                
      
    删除页面
    • ByteArrayInputStream swapStream = new ByteArrayInputStream(spire.toByteArray());
      XWPFDocument document1 = new XWPFDocument(swapStream);
      document1.removeBodyElement(0);
      document1.write(outputStream);
      

    生成水印

    图片加水印

    • 利用两层循环加水印,对比水印图片宽高和原图宽高。

    • @Component
      public class ImageWaterMarker implements MyWaterMarker {
      
          private static final int HEIGHT_STEP = 100;
      
          private static final int WIDTH_STEP = 80;
          
          private static final int ROTATE =150;
      
          private static final String WATER_MARK_PATH = "watermark/watermark.png";
      
          @Override
          public String getFileType(String mimeType) {
              return MimeTypeFileType.IMAGE.findFileType(mimeType);
          }
          
          @Override
          public Boolean watermark(InputStream inputStream, OutputStream outputStream, String mimeType) {
              try {
                  BufferedImage original = ImageIO.read(inputStream);
                  String fileType = getFileType(mimeType);
                  ClassPathResource classPathResource = new ClassPathResource(WATER_MARK_PATH);
                  //获取水印图片
                  BufferedImage markImage = ImageIO.read(classPathResource.getInputStream());
                  // determine image type and handle correct transparency
                  Graphics2D g2d = original.createGraphics();
                  //透明度
                  g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.7f));
                  //角度
                  g2d.rotate(ROTATE);
                  //获取整个图片高度
                  int canvasHeight = original.getHeight();
                  //获取整个图片宽度
                  int canvasWidth = original.getWidth();
                  //水印高度
                  int markHeight = markImage.getHeight();
                  //水印宽度
                  int markWidth = markImage.getWidth();
                  for(int i=-canvasHeight;i<canvasWidth+canvasHeight;i=i+markWidth+WIDTH_STEP){
                      for(int j=-canvasWidth;j<canvasHeight+canvasWidth;j=j+markHeight+HEIGHT_STEP){
                          g2d.drawImage(markImage,i,j,markImage.getWidth(),markImage.getHeight(),null);
                      }
                  }
                  g2d.dispose();
                  ImageIO.write(original, fileType, outputStream);
                  return true;
              } catch (IOException e) {
                  e.printStackTrace();
                  return false;
              }
          }
      }
      

    PDF加水印

    • 由于项目中针对流来操作加水印。

    • 目前主流的项目部署方式时jar包形式,在jar包中获取文件,只能通过流的形式【此处是获取水印图片】

      • ClassPathResource classPathResource = new ClassPathResource(WATER_MARK_PATH);
        classPathResource.getInputStream();
        
    • pdfbox没有提供以流的形式加载

      • 重写了以流的形式生成PDImageXObject

        •     public static PDImageXObject createFromFileByExtension(InputStream inputStream,String filename, PDDocument doc) throws IOException
              {
                  int dot = filename.lastIndexOf('.');
                  if (dot == -1)
                  {
                      throw new IllegalArgumentException("Image type not supported: " + filename);
                  }
                  String ext = filename.substring(dot + 1).toLowerCase();
                  if ("jpg".equals(ext) || "jpeg".equals(ext))
                  {
                      PDImageXObject imageXObject = JPEGFactory.createFromStream(doc, inputStream);
                      inputStream.close();
                      return imageXObject;
                  }
                  if ("gif".equals(ext) || "bmp".equals(ext) || "png".equals(ext))
                  {
                      BufferedImage bim = ImageIO.read(inputStream);
                      return LosslessFactory.createFromImage(doc, bim);
                  }
                  throw new IllegalArgumentException("Image type not supported: " + filename);
              }
          
    • 最终代码

      • @Component
        public class PdfWaterMarker implements MyWaterMarker {
            
            private static final int HEIGHT_STEP = 100;
        
            private static final int WIDTH_STEP = 80;
        
            private static final double THETA = 30;
        
            private static final String WATER_MARK_PATH = "watermark/watermark.png";
        
            @Override
            public String getFileType(String mimeType) {
                return MimeTypeFileType.PDF.findFileType(mimeType);
            }
            
            @Override
            public Boolean watermark(InputStream inputStream, OutputStream outputStream, String mimeType) {
                try {
                    //打开pdf文件
                    PDDocument doc = PDDocument.load(inputStream);
                    doc.setAllSecurityToBeRemoved(true);
                    //遍历pdf所有页
                    for (PDPage page : doc.getPages()) {
                        ClassPathResource classPathResource = new ClassPathResource(WATER_MARK_PATH);
                        //创建PDImageXObject对象
                        PDImageXObject imageXObject = createFromFileByExtension(classPathResource.getInputStream(),classPathResource.getFilename(),doc);
                        PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
                        PDExtendedGraphicsState pdExtGfxState = new PDExtendedGraphicsState();
                        // 水印透明度
                        pdExtGfxState.setNonStrokingAlphaConstant(0.8f);
                        pdExtGfxState.setAlphaSourceFlag(true);
                        pdExtGfxState.getCOSObject().setItem(COSName.BM, COSName.MULTIPLY);
                        cs.setGraphicsStateParameters(pdExtGfxState);
                        for(int y= 0; y <= page.getMediaBox().getHeight();y =  (y+imageXObject.getHeight()+HEIGHT_STEP)){
                            for(int x= 0; x <= page.getMediaBox().getWidth();x = (x+imageXObject.getWidth()+WIDTH_STEP)){
                                cs.saveGraphicsState();
                                Matrix rotate = new Matrix();
                                rotate.rotate(Math.toRadians(THETA));
                                cs.transform(rotate);
                                cs.drawImage(imageXObject, x, y);
                                cs.restoreGraphicsState();
                            }
                        }
                        cs.close();
                    }
                    doc.save(outputStream);
                    doc.close();
                    return true;
                } catch (IOException e) {
                    e.printStackTrace();
                    return false;
                }
            }
        
            public static PDImageXObject createFromFileByExtension(InputStream inputStream,String filename, PDDocument doc) throws IOException
            {
                int dot = filename.lastIndexOf('.');
                if (dot == -1)
                {
                    throw new IllegalArgumentException("Image type not supported: " + filename);
                }
                String ext = filename.substring(dot + 1).toLowerCase();
                if ("jpg".equals(ext) || "jpeg".equals(ext))
                {
                    PDImageXObject imageXObject = JPEGFactory.createFromStream(doc, inputStream);
                    inputStream.close();
                    return imageXObject;
                }
                if ("gif".equals(ext) || "bmp".equals(ext) || "png".equals(ext))
                {
                    BufferedImage bim = ImageIO.read(inputStream);
                    return LosslessFactory.createFromImage(doc, bim);
                }
                throw new IllegalArgumentException("Image type not supported: " + filename);
            }
        
        }
        

    Word加水印

    • 本身使用free spire .doc for java操作word文档加水印非常简单,奈何开源版有官方文字。不得已使用free spire .doc for java + apache poi形式

    • @Component
      public class WordWaterMarker implements MyWaterMarker {
          
          private static final String WATER_MARK_PATH = "watermark/watermark-rotate.png";
      
          private static final Integer SCALING = 120;
      
          @Override
          public String getFileType(String mimeType) {
              return MimeTypeFileType.WORD.findFileType(mimeType);
          }
      
          @Override
          public Boolean watermark(InputStream inputStream, OutputStream outputStream, String mimeType) {
              ByteArrayOutputStream spire = null;
              try {
                  spire = new ByteArrayOutputStream();
                  //加载Word文档
                  Document document = new Document();
                  document.loadFromStream(inputStream, FileFormat.Auto);
                  //获取第一个节,由于Free Spire for java 会在word开头添加文字 The document was created with Spire.DOC for Java
                  //解决方案是 ,先添加空白页,然后使用Apache POI 删除空白页
                  Section section1 = new Section(document);
                  document.getSections().insert(0,section1);
                  //创建PictureWatermark实例
                  PictureWatermark picture = new PictureWatermark();
                  ClassPathResource classPathResource = new ClassPathResource(WATER_MARK_PATH);
                  //设置水印图片属性
                  picture.setPicture(classPathResource.getInputStream());
                  picture.setScaling(SCALING);
                  picture.isWashout(false);
                  //添加水印图片到文档
                  document.setWatermark(picture);
                  //保存结果文件
                  document.saveToFile(spire, FileFormat.Auto );
                  //POI 去除第一行空白页
                  ByteArrayInputStream swapStream = new ByteArrayInputStream(spire.toByteArray());
                  XWPFDocument document1 = new XWPFDocument(swapStream);
                  document1.removeBodyElement(0);
                  document1.write(outputStream);
                  return true;
              } catch (Exception e) {
                  e.printStackTrace();
                  return false;
              } finally {
                  if (spire != null) {
                      try {
                          spire.close();
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
          }
      }
      

    其他

    • 在项目中,加水印用上设计模式:策略模式+工厂模式。

    • 分析:

      • 水印功能可以看做针对不同文件做水印操作。那就可以抽象出水印接口

      • /**
         * 策略模式
         */
        public interface MyWaterMarker {
        
            /**
             * 获取流大小,反射获取contentWritten
             * 目前没找到其他好方法
             * @param res
             * @return
             */
            default Long getLength(HttpServletResponse res){
                try {
                    if(res instanceof OnCommittedResponseWrapper){
                        Field contentWritten = res.getClass().getSuperclass().getDeclaredField("contentWritten");
                        contentWritten.setAccessible(true);
                        return (long) contentWritten.get(res);
                    }
        
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                return null;
            }
        
            /**
             * 获取文件类型
             * @param mimeType
             * @return
             */
            String getFileType(String mimeType);
        
            /**
             * 是否支持
             * @param mimeType
             * @return
             */
            default Boolean support(String mimeType){
                return ObjectUtils.isNotEmpty(getFileType(mimeType));
            }
        
            /**
             * 加水印
             * @param inputStream
             * @param outputStream
             * @param mimeType
             */
            Boolean watermark(InputStream inputStream, OutputStream outputStream, String mimeType);
        }
        
    • 图片水印、pdf水印、word水印分别实现接口来实现不同类型的水印功能

      • ImageWaterMarker

        • @Component
          public class ImageWaterMarker implements MyWaterMarker {
          
              private static final int HEIGHT_STEP = 100;
          
              private static final int WIDTH_STEP = 80;
              
              private static final int ROTATE =150;
          
              private static final String WATER_MARK_PATH = "watermark/watermark.png";
          
              @Override
              public String getFileType(String mimeType) {
                  return MimeTypeFileType.IMAGE.findFileType(mimeType);
              }
              
              @Override
              public Boolean watermark(InputStream inputStream, OutputStream outputStream, String mimeType) {
                  try {
                      BufferedImage original = ImageIO.read(inputStream);
                      String fileType = getFileType(mimeType);
                      ClassPathResource classPathResource = new ClassPathResource(WATER_MARK_PATH);
                      //水印图片
                      BufferedImage markImage = ImageIO.read(classPathResource.getInputStream());
                      // determine image type and handle correct transparency
                      Graphics2D g2d = original.createGraphics();
                      //透明度
                      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.7f));
                      //角度
                      g2d.rotate(ROTATE);
                      int canvasHeight = original.getHeight();
                      int canvasWidth = original.getWidth();
                      int markHeight = markImage.getHeight();
                      int markWidth = markImage.getWidth();
                      for(int i=-canvasHeight;i<canvasWidth+canvasHeight;i=i+markWidth+WIDTH_STEP){
                          for(int j=-canvasWidth;j<canvasHeight+canvasWidth;j=j+markHeight+HEIGHT_STEP){
                              g2d.drawImage(markImage,i,j,markImage.getWidth(),markImage.getHeight(),null);
                          }
                      }
                      g2d.dispose();
                      ImageIO.write(original, fileType, outputStream);
                      return true;
                  } catch (IOException e) {
                      e.printStackTrace();
                      return false;
                  }
              }
          }
          
      • PdfWaterMarker

        • @Component
          public class PdfWaterMarker implements MyWaterMarker {
              
              private static final int HEIGHT_STEP = 100;
          
              private static final int WIDTH_STEP = 80;
          
              private static final double THETA = 30;
          
              private static final String WATER_MARK_PATH = "watermark/watermark.png";
          
              @Override
              public String getFileType(String mimeType) {
                  return MimeTypeFileType.PDF.findFileType(mimeType);
              }
              
              @Override
              public Boolean watermark(InputStream inputStream, OutputStream outputStream, String mimeType) {
                  try {
                      //打开pdf文件
                      PDDocument doc = PDDocument.load(inputStream);
                      doc.setAllSecurityToBeRemoved(true);
                      //遍历pdf所有页
                      for (PDPage page : doc.getPages()) {
                          ClassPathResource classPathResource = new ClassPathResource(WATER_MARK_PATH);
                          //创建PDImageXObject对象
                          PDImageXObject imageXObject = createFromFileByExtension(classPathResource.getInputStream(),classPathResource.getFilename(),doc);
                          PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
                          PDExtendedGraphicsState pdExtGfxState = new PDExtendedGraphicsState();
                          // 水印透明度
                          pdExtGfxState.setNonStrokingAlphaConstant(0.8f);
                          pdExtGfxState.setAlphaSourceFlag(true);
                          pdExtGfxState.getCOSObject().setItem(COSName.BM, COSName.MULTIPLY);
                          cs.setGraphicsStateParameters(pdExtGfxState);
                          for(int y= 0; y <= page.getMediaBox().getHeight();y =  (y+imageXObject.getHeight()+HEIGHT_STEP)){
                              for(int x= 0; x <= page.getMediaBox().getWidth();x = (x+imageXObject.getWidth()+WIDTH_STEP)){
                                  cs.saveGraphicsState();
                                  Matrix rotate = new Matrix();
                                  rotate.rotate(Math.toRadians(THETA));
                                  cs.transform(rotate);
                                  cs.drawImage(imageXObject, x, y);
                                  cs.restoreGraphicsState();
                              }
                          }
                          cs.close();
                      }
                      doc.save(outputStream);
                      doc.close();
                      return true;
                  } catch (IOException e) {
                      e.printStackTrace();
                      return false;
                  }
              }
          
              public static PDImageXObject createFromFileByExtension(InputStream inputStream,String filename, PDDocument doc) throws IOException
              {
                  int dot = filename.lastIndexOf('.');
                  if (dot == -1)
                  {
                      throw new IllegalArgumentException("Image type not supported: " + filename);
                  }
                  String ext = filename.substring(dot + 1).toLowerCase();
                  if ("jpg".equals(ext) || "jpeg".equals(ext))
                  {
                      PDImageXObject imageXObject = JPEGFactory.createFromStream(doc, inputStream);
                      inputStream.close();
                      return imageXObject;
                  }
                  if ("gif".equals(ext) || "bmp".equals(ext) || "png".equals(ext))
                  {
                      BufferedImage bim = ImageIO.read(inputStream);
                      return LosslessFactory.createFromImage(doc, bim);
                  }
                  throw new IllegalArgumentException("Image type not supported: " + filename);
              }
          
          }
          
      • WordWaterMarker

        • @Component
          public class WordWaterMarker implements MyWaterMarker {
              
              private static final String WATER_MARK_PATH = "watermark/watermark-rotate.png";
          
              private static final Integer SCALING = 120;
          
              @Override
              public String getFileType(String mimeType) {
                  return MimeTypeFileType.WORD.findFileType(mimeType);
              }
          
              @Override
              public Boolean watermark(InputStream inputStream, OutputStream outputStream, String mimeType) {
                  ByteArrayOutputStream spire = null;
                  try {
                      spire = new ByteArrayOutputStream();
                      //加载Word文档
                      Document document = new Document();
                      document.loadFromStream(inputStream, FileFormat.Auto);
                      //获取第一个节,由于Free Spire for java 会在word开头添加文字 The document was created with Spire.DOC for Java
                      //解决方案是 ,先添加空白页,然后使用Apache POI 删除空白页
                      Section section1 = new Section(document);
                      document.getSections().insert(0,section1);
                      //创建PictureWatermark实例
                      PictureWatermark picture = new PictureWatermark();
                      ClassPathResource classPathResource = new ClassPathResource(WATER_MARK_PATH);
                      //设置水印图片属性
                      picture.setPicture(classPathResource.getInputStream());
                      picture.setScaling(SCALING);
                      picture.isWashout(false);
                      //添加水印图片到文档
                      document.setWatermark(picture);
                      //保存结果文件
                      document.saveToFile(spire, FileFormat.Auto );
                      //POI 去除第一行空白页
                      ByteArrayInputStream swapStream = new ByteArrayInputStream(spire.toByteArray());
                      XWPFDocument document1 = new XWPFDocument(swapStream);
                      document1.removeBodyElement(0);
                      document1.write(outputStream);
                      return true;
                  } catch (Exception e) {
                      e.printStackTrace();
                      return false;
                  } finally {
                      if (spire != null) {
                          try {
                              spire.close();
                          } catch (IOException e) {
                              e.printStackTrace();
                          }
                      }
                  }
              }
          }
          
    • 水印功能实现类作为bean放入spring容器中。在生成逻辑中,是根据文件类型做判断,接口中提供了support方法来作为类是否支持文件水印。此时需要一个类来管理所有的水印功能类,创建一个RivTrustWaterMarkFactory。利用Spring bean的生命周期,在所有bean加载完成后,为RivTrustWaterMarkFactory整合WordRivTrustWaterMarker,PdfRivTrustWaterMarker,ImageRivTrustWaterMarker

    • 方法有两种

      1. MyWaterMarkFactory实现ApplicationListener监听ContextRefreshedEvent事件

      2. MyWaterMarkFactory实现CommandLineRunner接口实现 run(String… args)方法

        • @Override	
          public void run(String... args) throws Exception {
              initStrategyMap();
          }
          
    • RivTrustWaterMarkFactory

      • /**
         * 工厂模式,
         */
        @Component
        public class MyWaterMarkFactory implements ApplicationListener, ApplicationContextAware {
            
            
            private List<MyWaterMarker> waterMarkers = new ArrayList<>();
            
            private ApplicationContext applicationContext;
            @Resource
            private WithOutWaterMarker withOutWaterMarker;
        
            @Override
            public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
                this.applicationContext = applicationContext;
            }
        
            /**
             * 监听事件,从spring工厂中获取所有RivTrustWaterMark Bean
             * @param event
             */
            @Override
            public void onApplicationEvent(ApplicationEvent event) {
                if( event instanceof ContextRefreshedEvent){
                    Map<String, MyWaterMarker> beansOfType = this.applicationContext.getBeansOfType(RivTrustWaterMarker.class);
                    waterMarkers = beansOfType.values().stream().collect(Collectors.toList());
                }
            }
        
            public RivTrustWaterMarker support(String filename) {
                for (RivTrustWaterMarker rivTrustWaterMarker : waterMarkers) {
                    if(rivTrustWaterMarker.support( filename)){
                        return rivTrustWaterMarker;
                    }
                }
                return withOutTrustWaterMarker;
            }
        
        
        }
        
    展开全文
  • Java使用Spire讲网页保存为PDF并去除Evaluation Warning水印方案,https://blog.csdn.net/kewen_123/article/details/121025630
  • 豆丁文库下载文件水印去除的方法,前提要有PS
  • 安装好试用版的simca14.1,打开该程序点击patch找到simca启动文件点ok,界面最后一行显示ok,则破解成功。
  • Ckfinder 2.4.2 去除水印文件移动限制方法 去除缩略图(面板)上方的版权提示 去除左下角的版权提示 去除文件移动限制 去除帮助按
  • PDF文件的文字水印去除去器,基于 Apache PDFBox实现
  • 图片水印去除工具

    2019-01-04 15:15:12
    相信我,这个是你用过最好用水印去除工具,哈哈~什么污渍修复不在话下
  • 自动识别mp4视频的水印, 并去除,生成新的视频文件(无音频)
  • gojs去除水印方式

    2018-05-18 08:40:06
    通过npm安装gojs官方依赖,或者其他方式安装依赖之后,将该同文件名的文件替换即可去除水印。npm安装执行npm i gojs --save,之前一直是npm install gojs有问题。
  • 前天有朋友问我怎么在PS里面去除文字图片的水印问题,他说,按照网上百度的处理的效果不是太明显,处理后的文字也变模糊了!关于这个问题,分享一下我的PS处理文字上面带水印的方法! 这个方法用的软件:Photoshop...

    前天有朋友问我怎么在PS里面去除文字图片的水印问题,他说,按照网上百度的处理的效果不是太明显,处理后的文字也变模糊了!关于这个问题,分享一下我的PS处理文字上面带水印的方法!

    这个方法用的软件:Photoshop,俗称PS,核心思路:覆盖水印,改变图层混合模式!

    1. 打开PS,导入需要修图的图片文件,Ctrl+J,复制一层背景素材,备份避免损坏!

    带水印的文字素材

    复制一层背景

    2.用矩形工具或钢笔工具,将logo水印区域的大致勾选出来,尽量全部覆盖,填充颜色为水印色(可以用吸管提取一下水印色);,然后将所有的水印用我们选好的区域都遮盖住,遮盖的图层,按着shift由上到下全部选中,Ctrl+E合并图层!

    PS中用这种方法去水印,不干净了算我的

    3.将上面的矩形区域或填充色背景的图层模式切换,有的时候用“实色混合”、“划分”,或者“强光”等模式,颜色不同模式不一样,可以一个个的尝试遮盖色彩模式,最后合并图层即可!这样就修好了,没有水印了!

    PS中用这种方法去水印,不干净了算我的

    不过这种方法适合纯色、单色的水印logo,而且效果比较好,对于单色水印,就用这样的方法一定能处理好的!

    现在给大家介绍一款图片一键去水印的超好用的软件——水印云,具体步骤如下:

     水印云

    步骤一:在浏览器上搜索“水印云”或者网址(如图所示),打开水印云官网,点击“立即体验”;

     步骤二:注册一个账号并登录,点击“图片去水印”;

    步骤三:点击“添加文件”,并本地上传有水印图片;

    步骤四:选择左上角框选工具框选水印“果壳”,选择右上角“开始去水印”,去除水印后,下载文件保存本地电脑即可。

    处理好的效果图如下:

    展开全文
  • PDF文件JAVA去水印源码pd4ml-例子 实际的PD4ML v4版本 v4.0.4 仍然有一些限制(与 v3.11 相比):缺少专有的标签支持和 generateMulticolumn() API 调用,一些属性被忽略; 其他一些。 这些功能将在即将发布的版本中...
  • PDF文件怎么去掉水印

    2019-04-26 16:28:45
    而且有的PDF文件中含有水印的,这样非常影响阅读体验,那如何才能批量去除PDF文件中的水印呢? 步骤一:打开电脑进入浏览器内搜索“迅捷pdf在线转换器”(需提前准备好PDF文件) 步骤二:进入在线转换的页面后,...

    PDF格式的文件已经普及在我们的办公之中。但PDF文件以其安全性而出名,不能直接对其进行编辑修改。而且有的PDF文件中含有水印的,这样非常影响阅读体验,那如何才能批量去除PDF文件中的水印呢?
    在这里插入图片描述
    步骤一:打开电脑进入浏览器内搜索“迅捷pdf在线转换器”(需提前准备好PDF文件)
    在这里插入图片描述
    步骤二:进入在线转换的页面后,可以看到很多关于PDF文件的转换,这个时候不要看花了眼,找到文档处理,在下拉框里下回弹出“PDF去除水印”。
    在这里插入图片描述
    步骤三:进入去除水印的页面后点击页面内的“点击选择文件”将需要去除水印的PDF文件添加至页面内。
    在这里插入图片描述
    步骤四:输入需要删除的水印内容,然后点击开始删除的按钮。
    在这里插入图片描述
    步骤五:开始删除后,后台系统会自动进行删除,耐心等待一会,删除的时间是根据删除的文件大小来判断的。
    在这里插入图片描述
    步骤六:删除完成后就可以将文件保存至桌面上了,也可以在页面里面看看是否删除完全了。
    在这里插入图片描述
    去除PDF文件得水印到此就全部结束了,去除水印后的PDF文件,不会改变排版以及其他元素,小编已经尝试过了,有需要的朋友一起尝试下哦。

    展开全文
  • 用Python去除PDF水印尝试

    千次阅读 2022-03-13 12:57:10
    最近在下载PDF书籍的时候,发现有些PDF有水印,于是就寻思着能不能用Python去除这些讨厌的水印 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,037
精华内容 2,814
关键字:

如何去除文件水印