精华内容
下载资源
问答
  • 2020-12-04 23:01:12

    前段时间换工作,在BOSS直聘上看到一个有意思的功能,上传docx格式的简历,能够以图片的形式在线预览,并且图片还添加了水印,笔者对此比较感兴趣,就摸索着实现方法。网上逛了一圈,对于docx直接转图片这种转换没有什么有效的信息,不过结合获取的信息,笔者倒是想了一个曲线救国的法子,docx->pdf, pdf->image,通过两步可以最终实现该转换。

    一、环境准备

    首先进行环境准备工作,把需要用到的工具都安装配置好:

    1、安装pandoc

    Pandoc是由John MacFarlane开发的标记语言转换工具,可实现不同标记语言间的格式转换,堪称该领域中的“瑞士军刀”。该工具使用Haskell语言编写,以命令行形式实现与用户的交互,可支持多种操作系统。简而言之,pandoc就是一款转换工具,可以把格式A的文档转换为格式B的文档,就本文的目标来讲,主要用它实现了docx->pdf的转换。

    根据系统类别选择对应的安装包,安装完成后将其安装目录添加到系统路径中,windows版本的安装完成后会自动添加,不用额外设置。

    2、安装miktex

    MikTex是一款基于Tex的排版引擎。TeX 在不同的硬件和操作系统上有不同的实现版本。这就像C语言,在不同的操作系统中有不同的编译系统,例如Linux 下的gcc,Windows 下的Visual C++ 等。有时,一种操作系统里也会有好几种的TeX系统。目前常见的Unix/Linux 下的TeX系统是Texlive,Windows 下则有MiKTeX和fpTeX。CTeX指的是CTeX中文套装的简称,是把MiKTeX和一些常用的相关工具,如GSview,WinEdt 等包装在一起制作的一个简易安装程序,并对其中的中文支持部分进行了配置,使得安装后马上就可以使用中文。

    该排版工具是docx->pdf转换时不可获取的,否则无法实现转换。

    下载地址:https://miktex.org/   根据系统类别选择合适的版本,安装完成后将安装目录添加到系统路径。

    3、安装poppler

    代码实现中引用了一个开源库pdf2image,而这个库又引用了poppler,所以需要安装该环境。Poppler是一个基于xpdf-3.0的用于操作pdf的库,其中poppler-utils是建立在Poppler的库API上的工具集合,用于管理PDF和提取内容,主要工具如下:

    pdfdetach – 从PDF中提取嵌入式文档;

    pdffonts – 列出PDF中使用的字体;

    pdfimages – 从PDF中以原始分辨率提取所有嵌入式图像;

    pdfinfo – 列出PDF的所有信息;

    pdfseparate – 从PDF中提取单个页面;

    pdftocairo – 使用cairo将单页从PDF转换为矢量或位图格式;

    pdftohtml – 将PDF转换为HTML格式的保留格式;

    pdftoppm – 将PDF页面转换为位图;

    pdftops – 将PDF转换为可打印的PS格式;

    pdftotext – 从PDF中提取所有文本;

    pdfunite – 合并几个PDF。

    pdf2image使用了pdftoppm和pdfinfo这两个工具,用来将pdf转换为图片和获取pdf的文档页数,代码稍后会列出。

    下载地址:https://github.com/Belval/pdf2image  根据系统类别选择对应的版本,安装完成后将安装目录下的bin目录添加到系统路径。

    4、字体下载

    用来生成水印时使用,笔者下载的是SimSun宋体,下载地址:https://www.fontke.com/font/10132367/download/,也可以下载其他字体,看个人选择。

    完成上边四步环境就配置好了,笔者的电脑是Windows10,当然以上工具同样支持linux和mac环境,每个工具的官档都标注了支持的系统版本。环境配置好后接下来就是coding环节了,通过程序来实现转换过程的自动化调用,笔者会列出代码的目录结构,并依次说明其用途。

    二、代码实现

    关于实现这部分,笔者使用的开发语言是python36,以下为目录结构:

    1、font目录

    该目录存放的是下载好的字体文件,供代码中引用。

    2、pdf目录

    该目录存放转换之后的pdf文件。

    3、target目录

    该目录存放最终转换后的图片,图片为以时间戳命名的png图片,格式可以指定。

    4、config.py

    配置文件,存放了目录、图片大小、水印等配置,代码如下:

    Python

    import os

    # 根目录

    BASE_DIR = os.path.dirname(__file__)

    # pdf默认输出路径

    DEFAULT_OUTPUT_DIR = os.path.join(BASE_DIR, 'pdf')

    # 最终生成的图片存放在此目录

    TARGET_DIR = os.path.join(BASE_DIR, 'target')

    # 水印字体

    FONT_FILE = os.path.join(BASE_DIR, "font/simsun.ttf")

    # 单张图片的宽高,PIL支持图片的最大宽度1700

    IMAGE_WIDTH = 1700

    IMAGE_HEIGHT = 2200

    # 水印位置-left和top

    WATERMARK_LEFT = 0

    WATERMARK_TOP = 1800

    # 水印图片背景色-白色透明,最后一位表示透明度0~255,0为透明

    BACKGROUND_COLOR = (255, 255, 255, 0)

    #水印字体颜色-红色 60透明度

    FONT_COLOR = (255, 0, 0, 60)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    importos

    # 根目录

    BASE_DIR=os.path.dirname(__file__)

    # pdf默认输出路径

    DEFAULT_OUTPUT_DIR=os.path.join(BASE_DIR,'pdf')

    # 最终生成的图片存放在此目录

    TARGET_DIR=os.path.join(BASE_DIR,'target')

    # 水印字体

    FONT_FILE=os.path.join(BASE_DIR,"font/simsun.ttf")

    # 单张图片的宽高,PIL支持图片的最大宽度1700

    IMAGE_WIDTH=1700

    IMAGE_HEIGHT=2200

    # 水印位置-left和top

    WATERMARK_LEFT=0

    WATERMARK_TOP=1800

    # 水印图片背景色-白色透明,最后一位表示透明度0~255,0为透明

    BACKGROUND_COLOR=(255,255,255,0)

    #水印字体颜色-红色 60透明度

    FONT_COLOR=(255,0,0,60)

    5、doc2pdf.py

    该模块封装了pandoc命令行工具的调用,实现了docx文档到pdf的转换过程

    Python

    import os

    import uuid

    from subprocess import Popen, PIPE

    def _load_doc(doc):

    doc = str(doc)

    if not os.path.exists(doc):

    raise FileNotFoundError("file {} not found".format(doc))

    _, doc_name = os.path.split(doc)

    if not doc_name.endswith('.docx'):

    raise TypeError("Only support word doc with suffix '.docx'")

    return doc

    def _build_command(doc_path, output_dir, pdf_name=None, pdf_engine=None):

    args = ['pandoc', '--pdf-engine=xelatex']

    # args = ['pandoc', '--pdf-engine=lualatex']

    if pdf_engine is not None:

    # MikTex包含了两种pandoc支持的Tex

    if pdf_engine not in ("xelatex", "lualatex"):

    raise ValueError("not supported pdf-engine: {}".format(pdf_engine))

    else:

    args[1] = '--pdf-engine={}'.format(pdf_engine)

    if pdf_name is None:

    pdf_name = str(uuid.uuid4()) + '.pdf'

    if not os.path.isdir(output_dir):

    raise NotADirectoryError("{} is not a existed directory".format(output_dir))

    pdf_path = os.path.join(output_dir, pdf_name)

    args.append('-o')

    args.append(pdf_path)

    args.append(doc_path)

    # 设置字体避免中文乱码无法输出问题,SimSun是宋体, MicrosoftYaHei是微软雅黑

    args.append('-V')

    args.append('mainfont="MicrosoftYaHei"')

    # args.append('-V')

    # args.append('margin-left=0in')

    return args, pdf_path

    def doc2pdf(source, pdf_path):

    doc_path = _load_doc(source)

    cmd, output_pdf = _build_command(doc_path, pdf_path)

    # run cmd

    print("doc to pdf, converting...")

    Popen(cmd, stderr=PIPE, stdout=PIPE).communicate()

    print("job done!")

    return output_pdf

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    importos

    importuuid

    fromsubprocessimportPopen,PIPE

    def_load_doc(doc):

    doc=str(doc)

    ifnotos.path.exists(doc):

    raiseFileNotFoundError("file {} not found".format(doc))

    _,doc_name=os.path.split(doc)

    ifnotdoc_name.endswith('.docx'):

    raiseTypeError("Only support word doc with suffix '.docx'")

    returndoc

    def_build_command(doc_path,output_dir,pdf_name=None,pdf_engine=None):

    args=['pandoc','--pdf-engine=xelatex']

    # args = ['pandoc', '--pdf-engine=lualatex']

    ifpdf_engineisnotNone:

    # MikTex包含了两种pandoc支持的Tex

    ifpdf_enginenotin("xelatex","lualatex"):

    raiseValueError("not supported pdf-engine: {}".format(pdf_engine))

    else:

    args[1]='--pdf-engine={}'.format(pdf_engine)

    ifpdf_nameisNone:

    pdf_name=str(uuid.uuid4())+'.pdf'

    ifnotos.path.isdir(output_dir):

    raiseNotADirectoryError("{} is not a existed directory".format(output_dir))

    pdf_path=os.path.join(output_dir,pdf_name)

    args.append('-o')

    args.append(pdf_path)

    args.append(doc_path)

    # 设置字体避免中文乱码无法输出问题,SimSun是宋体, MicrosoftYaHei是微软雅黑

    args.append('-V')

    args.append('mainfont="MicrosoftYaHei"')

    # args.append('-V')

    # args.append('margin-left=0in')

    returnargs,pdf_path

    defdoc2pdf(source,pdf_path):

    doc_path=_load_doc(source)

    cmd,output_pdf=_build_command(doc_path,pdf_path)

    # run cmd

    print("doc to pdf, converting...")

    Popen(cmd,stderr=PIPE,stdout=PIPE).communicate()

    print("job done!")

    returnoutput_pdf

    6、pdf2image.py

    一个开源的python库,只包含了一个文件,笔者直接复制过来使用的。主要封装了poppler的命令行调用,实现pdf到图片的转换。

    Python

    """

    pdf2image is a light wrapper for the poppler-utils tools that can convert your

    PDFs into Pillow images.

    """

    import os

    import re

    import tempfile

    import uuid

    from io import BytesIO

    from subprocess import Popen, PIPE

    from PIL import Image

    def convert_from_path(pdf_path, dpi=200, output_folder=None, first_page=None, last_page=None, fmt='ppm', thread_count=1, userpw=None):

    """

    Description: Convert PDF to Image will throw whenever one of the condition is reached

    Parameters:

    pdf_path -> Path to the PDF that you want to convert

    dpi -> Image quality in DPI (default 200)

    output_folder -> Write the resulting images to a folder (instead of directly in memory)

    first_page -> First page to process

    last_page -> Last page to process before stopping

    fmt -> Output image format

    thread_count -> How many threads we are allowed to spawn for processing

    userpw -> PDF's password

    """

    page_count = __page_count(pdf_path, userpw)

    if thread_count < 1:

    thread_count = 1

    if first_page is None:

    first_page = 1

    if last_page is None or last_page > page_count:

    last_page = page_count

    # Recalculate page count based on first and last page

    page_count = last_page - first_page + 1

    if thread_count > page_count:

    thread_count = page_count

    reminder = page_count % thread_count

    current_page = first_page

    processes = []

    for _ in range(thread_count):

    # A unique identifier for our files if the directory is not empty

    uid = str(uuid.uuid4())

    # Get the number of pages the thread will be processing

    thread_page_count = page_count // thread_count + int(reminder > 0)

    # Build the command accordingly

    args, parse_buffer_func = __build_command(['pdftoppm', '-r', str(dpi), pdf_path], output_folder, current_page, current_page + thread_page_count - 1, fmt, uid, userpw)

    # Update page values

    current_page = current_page + thread_page_count

    reminder -= int(reminder > 0)

    # Spawn the process and save its uuid

    processes.append((uid, Popen(args, stdout=PIPE, stderr=PIPE)))

    images = []

    for uid, proc in processes:

    data, _ = proc.communicate()

    if output_folder is not None:

    images += __load_from_output_folder(output_folder, uid)

    else:

    images += parse_buffer_func(data)

    return images

    def convert_from_bytes(pdf_file, dpi=200, output_folder=None, first_page=None, last_page=None, fmt='ppm', thread_count=1, userpw=None):

    """

    Description: Convert PDF to Image will throw whenever one of the condition is reached

    Parameters:

    pdf_file -> Bytes representing the PDF file

    dpi -> Image quality in DPI

    output_folder -> Write the resulting images to a folder (instead of directly in memory)

    first_page -> First page to process

    last_page -> Last page to process before stopping

    fmt -> Output image format

    thread_count -> How many threads we are allowed to spawn for processing

    userpw -> PDF's password

    """

    with tempfile.NamedTemporaryFile('wb') as f:

    f.write(pdf_file)

    f.flush()

    return convert_from_path(f.name, dpi=dpi, output_folder=output_folder, first_page=first_page, last_page=last_page, fmt=fmt, thread_count=thread_count, userpw=userpw)

    def pdf_page_count(pdf, password=None):

    return __page_count(pdf, password)

    def __build_command(args, output_folder, first_page, last_page, fmt, uid, userpw):

    if first_page is not None:

    args.extend(['-f', str(first_page)])

    if last_page is not None:

    args.extend(['-l', str(last_page)])

    parsed_format, parse_buffer_func = __parse_format(fmt)

    if parsed_format != 'ppm':

    args.append('-' + parsed_format)

    if output_folder is not None:

    args.append(os.path.join(output_folder, uid))

    if userpw is not None:

    args.extend(['-upw', userpw])

    return args, parse_buffer_func

    def __parse_format(fmt):

    if fmt[0] == '.':

    fmt = fmt[1:]

    if fmt == 'jpeg' or fmt == 'jpg':

    return 'jpeg', __parse_buffer_to_jpeg

    if fmt == 'png':

    return 'png', __parse_buffer_to_png

    # Unable to parse the format so we'll use the default

    return 'ppm', __parse_buffer_to_ppm

    def __parse_buffer_to_ppm(data):

    images = []

    index = 0

    while index < len(data):

    code, size, rgb = tuple(data[index:index + 40].split(b'\n')[0:3])

    size_x, size_y = tuple(size.split(b' '))

    file_size = len(code) + len(size) + len(rgb) + 3 + int(size_x) * int(size_y) * 3

    images.append(Image.open(BytesIO(data[index:index + file_size])))

    index += file_size

    return images

    def __parse_buffer_to_jpeg(data):

    return [

    Image.open(BytesIO(image_data + b'\xff\xd9'))

    for image_data in data.split(b'\xff\xd9')[:-1] # Last element is obviously empty

    ]

    def __parse_buffer_to_png(data):

    images = []

    index = 0

    while index < len(data):

    file_size = data[index:].index(b'IEND') + 8 # 4 bytes for IEND + 4 bytes for CRC

    images.append(Image.open(BytesIO(data[index:index+file_size])))

    index += file_size

    return images

    def __page_count(pdf_path, userpw=None):

    try:

    if userpw is not None:

    proc = Popen(["pdfinfo", pdf_path, '-upw', userpw], stdout=PIPE, stderr=PIPE)

    else:

    proc = Popen(["pdfinfo", pdf_path], stdout=PIPE, stderr=PIPE)

    out, err = proc.communicate()

    except:

    raise Exception('Unable to get page count. Is poppler installed and in PATH?')

    try:

    # This will throw if we are unable to get page count

    return int(re.search(r'Pages:\s+(\d+)', out.decode("utf8", "ignore")).group(1))

    except:

    raise Exception('Unable to get page count. %s' % err.decode("utf8", "ignore"))

    def __load_from_output_folder(output_folder, uid):

    return [Image.open(os.path.join(output_folder, f)) for f in sorted(os.listdir(output_folder)) if uid in f]

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    102

    103

    104

    105

    106

    107

    108

    109

    110

    111

    112

    113

    114

    115

    116

    117

    118

    119

    120

    121

    122

    123

    124

    125

    126

    127

    128

    129

    130

    131

    132

    133

    134

    135

    136

    137

    138

    139

    140

    141

    142

    143

    144

    145

    146

    147

    148

    149

    150

    151

    152

    153

    154

    155

    156

    157

    158

    159

    160

    161

    162

    163

    164

    165

    166

    167

    168

    169

    170

    171

    172

    173

    174

    175

    176

    """

    pdf2image is a light wrapper for the poppler-utils tools that can convert your

    PDFs into Pillow images.

    """

    importos

    importre

    importtempfile

    importuuid

    fromioimportBytesIO

    fromsubprocessimportPopen,PIPE

    fromPILimportImage

    defconvert_from_path(pdf_path,dpi=200,output_folder=None,first_page=None,last_page=None,fmt='ppm',thread_count=1,userpw=None):

    """

    Description: Convert PDF to Image will throw whenever one of the condition is reached

    Parameters:

    pdf_path -> Path to the PDF that you want to convert

    dpi -> Image quality in DPI (default 200)

    output_folder -> Write the resulting images to a folder (instead of directly in memory)

    first_page -> First page to process

    last_page -> Last page to process before stopping

    fmt -> Output image format

    thread_count -> How many threads we are allowed to spawn for processing

    userpw -> PDF's password

    """

    page_count=__page_count(pdf_path,userpw)

    ifthread_count<1:

    thread_count=1

    iffirst_pageisNone:

    first_page=1

    iflast_pageisNoneorlast_page>page_count:

    last_page=page_count

    # Recalculate page count based on first and last page

    page_count=last_page-first_page+1

    ifthread_count>page_count:

    thread_count=page_count

    reminder=page_count%thread_count

    current_page=first_page

    processes=[]

    for_inrange(thread_count):

    # A unique identifier for our files if the directory is not empty

    uid=str(uuid.uuid4())

    # Get the number of pages the thread will be processing

    thread_page_count=page_count//thread_count+int(reminder>0)

    # Build the command accordingly

    args,parse_buffer_func=__build_command(['pdftoppm','-r',str(dpi),pdf_path],output_folder,current_page,current_page+thread_page_count-1,fmt,uid,userpw)

    # Update page values

    current_page=current_page+thread_page_count

    reminder-=int(reminder>0)

    # Spawn the process and save its uuid

    processes.append((uid,Popen(args,stdout=PIPE,stderr=PIPE)))

    images=[]

    foruid,procinprocesses:

    data,_=proc.communicate()

    ifoutput_folderisnotNone:

    images+=__load_from_output_folder(output_folder,uid)

    else:

    images+=parse_buffer_func(data)

    returnimages

    defconvert_from_bytes(pdf_file,dpi=200,output_folder=None,first_page=None,last_page=None,fmt='ppm',thread_count=1,userpw=None):

    """

    Description: Convert PDF to Image will throw whenever one of the condition is reached

    Parameters:

    pdf_file -> Bytes representing the PDF file

    dpi -> Image quality in DPI

    output_folder -> Write the resulting images to a folder (instead of directly in memory)

    first_page -> First page to process

    last_page -> Last page to process before stopping

    fmt -> Output image format

    thread_count -> How many threads we are allowed to spawn for processing

    userpw -> PDF's password

    """

    withtempfile.NamedTemporaryFile('wb')asf:

    f.write(pdf_file)

    f.flush()

    returnconvert_from_path(f.name,dpi=dpi,output_folder=output_folder,first_page=first_page,last_page=last_page,fmt=fmt,thread_count=thread_count,userpw=userpw)

    defpdf_page_count(pdf,password=None):

    return__page_count(pdf,password)

    def__build_command(args,output_folder,first_page,last_page,fmt,uid,userpw):

    iffirst_pageisnotNone:

    args.extend(['-f',str(first_page)])

    iflast_pageisnotNone:

    args.extend(['-l',str(last_page)])

    parsed_format,parse_buffer_func=__parse_format(fmt)

    ifparsed_format!='ppm':

    args.append('-'+parsed_format)

    ifoutput_folderisnotNone:

    args.append(os.path.join(output_folder,uid))

    ifuserpwisnotNone:

    args.extend(['-upw',userpw])

    returnargs,parse_buffer_func

    def__parse_format(fmt):

    iffmt[0]=='.':

    fmt=fmt[1:]

    iffmt=='jpeg'orfmt=='jpg':

    return'jpeg',__parse_buffer_to_jpeg

    iffmt=='png':

    return'png',__parse_buffer_to_png

    # Unable to parse the format so we'll use the default

    return'ppm',__parse_buffer_to_ppm

    def__parse_buffer_to_ppm(data):

    images=[]

    index=0

    whileindex

    code,size,rgb=tuple(data[index:index+40].split(b'\n')[0:3])

    size_x,size_y=tuple(size.split(b' '))

    file_size=len(code)+len(size)+len(rgb)+3+int(size_x)*int(size_y)*3

    images.append(Image.open(BytesIO(data[index:index+file_size])))

    index+=file_size

    returnimages

    def__parse_buffer_to_jpeg(data):

    return[

    Image.open(BytesIO(image_data+b'\xff\xd9'))

    forimage_dataindata.split(b'\xff\xd9')[:-1]# Last element is obviously empty

    ]

    def__parse_buffer_to_png(data):

    images=[]

    index=0

    whileindex

    file_size=data[index:].index(b'IEND')+8# 4 bytes for IEND + 4 bytes for CRC

    images.append(Image.open(BytesIO(data[index:index+file_size])))

    index+=file_size

    returnimages

    def__page_count(pdf_path,userpw=None):

    try:

    ifuserpwisnotNone:

    proc=Popen(["pdfinfo",pdf_path,'-upw',userpw],stdout=PIPE,stderr=PIPE)

    else:

    proc=Popen(["pdfinfo",pdf_path],stdout=PIPE,stderr=PIPE)

    out,err=proc.communicate()

    except:

    raiseException('Unable to get page count. Is poppler installed and in PATH?')

    try:

    # This will throw if we are unable to get page count

    returnint(re.search(r'Pages:\s+(\d+)',out.decode("utf8","ignore")).group(1))

    except:

    raiseException('Unable to get page count. %s'%err.decode("utf8","ignore"))

    def__load_from_output_folder(output_folder,uid):

    return[Image.open(os.path.join(output_folder,f))forfinsorted(os.listdir(output_folder))ifuidinf]

    7、main.py

    入口主程序,传入doc文档,得到png图片^_^

    Python

    import os

    import time

    from PIL import Image

    from PIL import ImageFont

    from PIL import ImageDraw

    from config import *

    from pdf2image import convert_from_path, pdf_page_count

    from doc2pdf import doc2pdf

    def doc2image(doc, fmt='png', output_dir=None, watermark=None, fpage=None, lpage=None):

    if output_dir is None:

    output_dir = TARGET_DIR

    target_name = os.path.join(output_dir, "{}.{}".format(int(time.time()), fmt))

    temp_pdf = doc2pdf(doc, pdf_path=DEFAULT_OUTPUT_DIR)

    if fpage is None:

    fpage = 1

    if lpage is not None:

    page_count = lpage - fpage + 1

    else:

    page_count = pdf_page_count(temp_pdf)

    print("pdf to image, converting...")

    to_image = _convert_pdf_to_image(temp_pdf, page_count, fmt, fpage, lpage)

    if watermark is not None:

    watermark_image = _make_watermark_image(to_image.size, watermark, page_count)

    # 合并内容图片和水印图片

    out = Image.alpha_composite(to_image, watermark_image)

    # out.show()

    # 转换为RGB模式才可保存为图片

    out.convert("RGB").save(target_name)

    else:

    to_image.save(target_name)

    print("job done!")

    def _convert_pdf_to_image(pdf, page_count, fmt, f, l, save=False):

    '''

    params:

    pdf: 待转换的pdf文件路径

    page_count: 要转换的页数

    fmt: 转换的图片格式

    f: 要转换的开始页数

    l: 结束页数

    save: 是否保留pdf文件,默认不保留

    '''

    # 根据页数转换为相应数量的图片

    image_list = convert_from_path(pdf, fmt=fmt, first_page=f, last_page=l)

    target_name = os.path.join(TARGET_DIR, "{}.{}".format(int(time.time()), fmt))

    to_image = Image.new('RGBA', (IMAGE_WIDTH, page_count * IMAGE_HEIGHT))

    for i, image in enumerate(image_list):

    # 计算高度,拼合单张图片到一整张图片上

    loc = (0, i * IMAGE_HEIGHT)

    to_image.paste(image, loc)

    if not save:

    try:

    os.remove(pdf)

    except Exception as e:

    print("fail to remove pdf, please check and remove it manually")

    return to_image

    def _make_watermark_image(image_size, watermark, count=1):

    '''

    生成水印图片

    params:

    image_size: 水印图片大小,与底板图片大小一致

    watermark: 水印文本

    count: 水印数量, 与内容页数保持一致

    '''

    fnt = ImageFont.truetype(font=FONT_FILE, size=80)

    watermark_image = Image.new('RGBA', image_size, color=BACKGROUND_COLOR)

    draw = ImageDraw.Draw(watermark_image)

    for i in range(1, count+1):

    draw.multiline_text((WATERMARK_LEFT, WATERMARK_TOP * i), watermark, font=fnt, fill=FONT_COLOR)

    return watermark_image

    if __name__ == '__main__':

    txt = "玩点coding https://vdcoding.com"

    doc = "resume.docx"

    doc2image(doc, watermark=txt)

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    importos

    importtime

    fromPILimportImage

    fromPILimportImageFont

    fromPILimportImageDraw

    fromconfigimport*

    frompdf2imageimportconvert_from_path,pdf_page_count

    fromdoc2pdfimportdoc2pdf

    defdoc2image(doc,fmt='png',output_dir=None,watermark=None,fpage=None,lpage=None):

    ifoutput_dirisNone:

    output_dir=TARGET_DIR

    target_name=os.path.join(output_dir,"{}.{}".format(int(time.time()),fmt))

    temp_pdf=doc2pdf(doc,pdf_path=DEFAULT_OUTPUT_DIR)

    iffpageisNone:

    fpage=1

    iflpageisnotNone:

    page_count=lpage-fpage+1

    else:

    page_count=pdf_page_count(temp_pdf)

    print("pdf to image, converting...")

    to_image=_convert_pdf_to_image(temp_pdf,page_count,fmt,fpage,lpage)

    ifwatermarkisnotNone:

    watermark_image=_make_watermark_image(to_image.size,watermark,page_count)

    # 合并内容图片和水印图片

    out=Image.alpha_composite(to_image,watermark_image)

    # out.show()

    # 转换为RGB模式才可保存为图片

    out.convert("RGB").save(target_name)

    else:

    to_image.save(target_name)

    print("job done!")

    def_convert_pdf_to_image(pdf,page_count,fmt,f,l,save=False):

    '''

    params:

    pdf: 待转换的pdf文件路径

    page_count: 要转换的页数

    fmt: 转换的图片格式

    f: 要转换的开始页数

    l: 结束页数

    save: 是否保留pdf文件,默认不保留

    '''

    # 根据页数转换为相应数量的图片

    image_list=convert_from_path(pdf,fmt=fmt,first_page=f,last_page=l)

    target_name=os.path.join(TARGET_DIR,"{}.{}".format(int(time.time()),fmt))

    to_image=Image.new('RGBA',(IMAGE_WIDTH,page_count*IMAGE_HEIGHT))

    fori,imageinenumerate(image_list):

    # 计算高度,拼合单张图片到一整张图片上

    loc=(0,i*IMAGE_HEIGHT)

    to_image.paste(image,loc)

    ifnotsave:

    try:

    os.remove(pdf)

    exceptExceptionase:

    print("fail to remove pdf, please check and remove it manually")

    returnto_image

    def_make_watermark_image(image_size,watermark,count=1):

    '''

    生成水印图片

    params:

    image_size: 水印图片大小,与底板图片大小一致

    watermark: 水印文本

    count: 水印数量, 与内容页数保持一致

    '''

    fnt=ImageFont.truetype(font=FONT_FILE,size=80)

    watermark_image=Image.new('RGBA',image_size,color=BACKGROUND_COLOR)

    draw=ImageDraw.Draw(watermark_image)

    foriinrange(1,count+1):

    draw.multiline_text((WATERMARK_LEFT,WATERMARK_TOP*i),watermark,font=fnt,fill=FONT_COLOR)

    returnwatermark_image

    if__name__=='__main__':

    txt="玩点coding https://vdcoding.com"

    doc="resume.docx"

    doc2image(doc,watermark=txt)

    三、待完善的地方

    笔者从网上下载了份docx格式的简历模板,通过上边的程序转换后得到的图片如下:

    从图中可以看到个人信息部分的样式跑偏了,这部分是在docx->pdf过程中的排版引擎决定的,所以想要获得完美的图片,先要好好研究下排版引擎的使用,排版引擎可以加载多种扩展包,用来支持不同的排版格式。笔者只是兴趣使然,在短时间内实现了docx到图片的转换,没有深入研究排版引擎部分。关于这种转换笔者能力有限,只能以这种繁琐的方式实现,不过笔者倒是很好奇BOSS直聘是如何实现的,如果有机会真心希望交流一下。

    更多相关内容
  • Word/wps怎么打印背景图片?对于使用WPS工作、学习的朋友们或许会遇到背景无法打印的问题,精美的背景、花纹常常是所做文档的一个可或缺的部分。那么我们该如何打印背景呢?小编在这里有多种办法。一、文本框法1...

    Word/wps怎么打印背景图片?对于使用WPS工作、学习的朋友们或许会遇到背景无法打印的问题,精美的背景、花纹常常是所做文档的一个不可或缺的部分。那么我们该如何打印出背景呢?小编在这里有多种办法。

    2b045ec7a5023dbbc08934aa8df92be9.png

    一、文本框法

    1、如图,点击【插入】--【文本框】,在文档内拖出任意大小的文本框,再调整到页面的大小。

    47eb3ef7b6d0a37befc343e737cae290.png

    1185315587b2ab1145eb7f845461afc9.png

    2、右键文本框,选择【设置对象格式】,在弹出窗口中选择【填充】。如果你的背景是纯色的话,就可以在各色块中选择想要的颜色。如果背景是个图片的话,就可以选择【填充效果】--【图案】,使用你喜爱的图片。

    cc5d46e9a948550b9c408ea3d5b9d78a.png

    1d5f9baf7c48da59a3d89ff909ec0cda.png

    3、成品图如下。这时,你可以试试打印了,你会惊喜地发现,背景被成功打印下来了。

    85960d3d93799ab7727af500ab7a7601.png

    二、图片置底法

    1、首先,打开你想要作为背景的图片。

    4d7d85774d5014b8c6c1881e31eec8a0.png

    57b726477e162bf64f2bf104cf27142e.png

    2、右键图片,选择【设置对象格式】--【版式】--【衬于文字下方】即可。

    a549a8ccd2644b919182fd3dca549be3.png

    39f718633465bf6362d2fc3ed27da8cd.png

    3、将图片调整成为页面大小覆盖住页面。接下来你就可以打字了。最后打印的成品也是会带有背景的。

    50d46103a23f51595163c43f501c2922.png

    三、二次打印法

    1、首先单独打印出你的背景。这里我就打印出了一张格点图作为背景。

    319e7cc772b7e6c447a29a320d137d01.png

    2、接着在同一张纸的同一面继续打印你的文本,如图,效果依旧完美。不过要注意的是,如果是在文印店打印的话,你可能要付两次打印的钱。

    1e8f5f9b7befd7302975964fad5bb8cc.png

    4f14386179aaec1f69939c7369ee18d7.png

    展开全文
  • 现如今,电脑的使用越来越普及,许多人上班或者生活中都需要用到word文档办公软件,但其中一些小知识,比如在word中怎么添加背景图片及文字背景?学习啦小编在这里给大家详细解答。在word中添加背景图文的教程有时候...

    现如今,电脑的使用越来越普及,许多人上班或者生活中都需要用到word文档办公软件,但其中一些小知识,比如在word中怎么添加背景图片及文字背景?学习啦小编在这里给大家详细解答。

    在word中添加背景图文的教程

    有时候我们会觉得空白的word背景实在是太单调了,想要给它添加一个背景,让它变得生动一些,具体应该如何操作呢?其实很简单。

    随便打开一个word文档

    点击工具栏的“格式”,选择“背景”

    点击“填充效果”

    7be86fa8c55ca12e01de780647d6faa8.png

    在word中添加背景图文的教程图1

    点击“图片”再点击“选择图片”

    69caeafa8a50e39d64e7d042f956584b.png

    在word中添加背景图文的教程图2

    开始选择你想要的图片比如我选定这一张,然后点击“插入”

    bc0b399df31da3c6febe74c9e0ee7d14.png

    在word中添加背景图文的教程图3

    点击“确定”这就是最后的效果了很可爱吧

    b8369fd64145eb5b327f7b77c34a0a06.png

    在word中添加背景图文的教程图4

    在word中加入背景图片的方法

    两种类型:

    一、以背景形式插入,这种插入形式可以在选项中选择不打印背景颜色和图片,生成的效果第一页都相同。插入方法:格式——背景——填充效果——图片——选择需插入的图片。

    二、页面中插入图片,这种方法跟正文一起被打印。插入方法有两种:

    1、调出页眉和眉脚视图,光标定位于页眉或页脚,插入图片,视图为衬于文字下方。(每页都有可设为各节不同)

    2、直接在页面中插入图片,并设置为衬于文字下方。(每页需单独插入)

    直接插入图片,然后双击图片,在第二项“大小”把图片大小设置成你想要的大小。然后右击图片——设置对象格式——版式——选择“衬于文字底下”。然后在图片工具栏调整图片的亮度和对比度

    背景图片可以在-页面布局-水印-自定义水印-图片水印-插入即可

    word文档中添加文字背景的方法

    你选择文字,进入格式菜单—边框和底纹,在底纹选项卡中选择底纹颜色,在右下角应用于框中选择文字,确定即可。或者直接点击格式工具栏上的突出显示按钮即可。

    在Microsoft word中插入背景图片的方法

    问题描述:就是说因为我要打字..得弄些背景,但总无法将字弄在背景图上,问一下个位该怎么弄呢??

    解决方法:

    “将字弄在背景图上”:

    1、菜单栏——图片——自来文件——选择图片后——确定;

    2、选图片——右键——设置图片格式——版式——衬于文字下方;

    3、菜单栏——插入——文本框(插入图形框、矩形框等)——输入文字;

    4、点文本框——菜单栏——格式——边框和底纹(点文本框右键进入格式也行)——颜色与线条:选“无填充颜色”和“无线条颜色”——确定;

    5、移文本框于图片之上——右键——叠放次序——置于顶层;

    6、按Shift,连选文本框和图片——右键——组合——组合;

    (以上文字就粘贴组合在图片上了)

    7、剪切图片;

    8、菜单栏——视图——页眉和页脚——点页眉——粘贴;

    (到这时图片就成背景了)——还可缩放移动或旋转

    9、最后,关闭“页眉和页脚”工具栏。

    如果是想把图片作为整张页面的背景,可以这样:

    一、用格式背景来设置文字的背景

    1.打开一篇编辑好的文章。

    2.单击“格式”——“背景”,选择“填充效果”。

    3.在“填充效果”对话框中——选择“图片”选项卡。

    4.然后,单击“选择图片”按钮,选择要目标图片,单击“插入”,再单击“确定”按钮。就可以插入一副图片作为Word的背景。

    问题:由于图片和文章版面大小不匹配,导致图片会重复与文章版面不和谐。

    解决:

    1. 利用PS或其它工具对图片进行处理,使之与文章版面大小匹配。

    2. 可以通过插入图片,并设置图片的版式来完成。(步骤如下:)

    二、设置背景图片:

    1.打开—编辑好的文章。

    2.单击菜单栏中的“插入”——“图片”——“来自文件”,

    3.然后,在对话框中找到目标图片,然后单击“插入”按钮就可以在Word文档中插入一副图片。

    4.此时,图片把文章的内容打乱:设计图片格式:格式|图片|打开设置图片对话框。

    5.设置图片版式|“衬于文字下方”此时,该图片设置为文章的背景图片。

    问题:图片的大小和文章的版式大小不匹配?

    解决:单击—“图片”|可以通过图片四角的小圆点来对图片进行放大,拖动起控制点接口调整背景图片的大小。

    如果仅是想在图片上写字,可以这样:

    1、打开word文档,输入要写的文字;

    2、在文字下方插入图片;

    3、在图片工具栏中点击文字环绕-----点击衬于文字下方;

    4、拉动图片大小,使文字衬于图片上方。此时,就可根据自己的需要设计字的大小、颜色及位置,并继续进行文字的编辑。

    图的环绕方式有一个叫衬于文字下方。设成这个就行了。如果想每页都有,就把图插到页眉里。在视图菜单中点页眉页脚,插入图片即可,也要改成衬于文字下方。

    >>>下一页更多精彩“Word把图片设为背景方法”

    展开全文
  • word怎么让背景图片铺满整个页面

    千次阅读 2021-01-14 03:46:16
    要把图片布满整个word中的A4界面中,以word2007为例,具体步骤如下:打开word之后,默认的界面就是A4界面大小,点击“插入”下面的“图片”,从电脑选择要铺满word页面的图片,点击“插入”;点击“文字环绕”的下拉...

    要把图片布满整个word中的A4界面中,以word2007为例,具体步骤如下:打开word之后,默认的界面就是A4界面大小,点击“插入”下面的“图片”,从电脑选择要铺满word页面的图片,点击“插入”; 点击“文字环绕”的下拉菜单,选择“衬于文字下方”; 用鼠标拖拽图片使它铺满整个页面; 调整好图片之后,即可看到图片布满整个word的A4界面了需要调整 页边距为0 图片铺满即可.www.how234.com防采集。

    首先打开文档,在页面上方的工具栏中,点击【页面布局】,找到并点击【背景】选项;

    最后我们拉动图片四个边上的调解按钮,这样我们调节的图片便成拖动铺满整页啦!方法二:图片为背景方式第一步:在文档的菜单栏上,我们点击“页面布局”菜单,在页面布局菜单

    在新界面的下方,点击【图片背景】,在【填充效果】窗口中,点击【选择图片】;

    插入-图片,选择图片,确定。 右击图片-自动换行-浮于文字上方,然后就可以随意拖动图片,更改大小让它铺满整页

    然后找到电脑中,自己想要设置的背景图片,选中后,点击【打开】;

    否则无法调整 解决办法1: 以前我们设置图片水印,都是通过格式-背景-水印-图片水印这 在word2007里,选择页面布局-》水印-》自定义水印-》图片水印,选择图片,输入合适的百

    最后点击【确定】,这时我们选择的图片,已经当做背景铺满了word文档的背景。

    专业术语叫出血。一般用PHOTOSHOP或CORELDRAW作版面设计,这样在成品裁切中即使略有偏差都可保证图片铺满整个页面。 而在word里插入图片,即使将页边距设置调

    1、打开Word文档2、按“Ctrl+P”调出打印机设置对话框3、单击“按纸张大小缩放”选项,选择需要的纸张大小即可,例如打印纸是A4纸,就选择A4纸,其余纸张类似选择内容来自www.how234.com请勿采集。

    展开全文
  • word2010里怎样填充页面背景图片

    千次阅读 2021-08-02 10:27:24
    Word2010中怎么把一张图片设置能背景图片Word2010中把一张图片设置成背景图片,使用填充效果...3、影响文字编辑,需要设置图片层次,完成设置成背景图片word2010怎么没有页面背景2010word设置一页背景图的...
  • 第1步,打开Word2013文档窗口,依次单击“文件”→“选项”按钮,如图1所示。图1 单击“选项”按钮第2步,在打开的“Word选项”对话框...(2)选中“打印背景色和图像”选项,可以打印Word文档设置的背景颜色和在Wo...
  • 2回答回答:Microsoft Word添加背景图片,将页面填充颜色设置为图片即可实现。方法步骤如下:1、打开需要操作的Word文档,在页面布局中找到并点击“页面颜色”,选择“填充效果”。2、点击图片标签页,然后点击...
  • css插入背景图片背景图片显示不出文件地址错了,是/而不是\word背景图片显示完整工具/材料:电脑、word。第一步,打脑脑,打开桌面,打开需辑的Word文档。第二步中需要修改的图片右键单击图片选择打开“文字环绕...
  • word中填充背景颜色的方法

    千次阅读 2021-08-21 17:52:02
    1、我们就需要先通过以下的设置来实现word背景颜色的打印效果,首先我们点击word文档左上角的word设置菜单图标,然后点击打开word选项。 2、在word选项窗口中我们点击左侧的显示菜单,然后在显示菜单列表中找到...
  • 原因是开启了360安全卫士的护眼模式导致的。 Step1 打开360安全卫士,找到健康助手 Step2 去掉 启用视觉包含豆沙绿色 勾选
  • 打印图片怎样去灰色底

    千次阅读 2020-12-20 12:50:45
    打印图片去灰色底的方法如下:1、首先在电脑上打开要进行操作的文档,然后使用鼠标左键选中有色的背景。2、接着在上方选项卡中点击“图片工具”,然后在其下方点击“设置透明色”功能选项。3、然后此时就会出现吸管...
  • 有时需要将公司一些重要文档发布到网页,但是希望这些重要文档打印、复制、下载。虽然将源文档转为PDF后可以通过密码实现打印和复制,但是PDF文件仍然可以被下载。以下可以简单解决以上问题(虽然彻底,...
  • word文档页面顺序调换

    2021-07-31 01:13:18
    word文档基本操作新建文档 我们讲了Word第一课后,有位朋友和我说用起来太麻烦了,问他怎么个麻烦法,他说,有时要打印几份文件,每打印一份就要退出一次Word重来,所以特别麻烦。 其实根本用着新建文档我们讲了...
  • 文章目录关于图片插入word,再转为pdf后,打印图片出现阴影模糊的问题及处理办法原因原始图片问题word软件本身问题处理办法软件选择office 2010Adobe Acrobat Pro处理 关于图片插入word,再转为pdf后,打印图片...
  • 有时候我们没办法得到pdf或者word文档,这个时候会使用手机或者相机进行拍照,往往会出现背景打印出来就是灰色的或者有黑色的背景,这个时候影响视野观看,通过代码实现对背景去除,还原清晰图像。代码如下: #!/...
  • 1、打开要阅读的Word文档,如下图所示,默认的页面背景色为白色。 2、找到菜单栏上的“页面布局按钮”,单击该按钮展开设置项。 3、在展开的设置项目中可以找到下图红色框内按钮,选择该按钮可以打开页面颜色...
  • Delphi 控件、文档居左、文档居右、文档居中或者是段落排列的排版、多级项目符号和编号、自定义页边空白和缩进样式、统一字符编码标准、背景图片打印预览、RTF输入和输出、HTML输出、现有的数据版本
  • 通过word模板输出完整word文件,纯前端vue package.json "file-saver": "^2.0.5", "jszip": "^3.6.0", "jszip-utils": "^0.1.0", "open-docxtemplater-image-module": "^1.0.3", "pizzip": "^3.0.6", "angular-...
  •  用户要求用程序生成标准的word文档,要能打印(有多个打印机时可以指定打印机进行打印,支持横向打印),而且能变形,以前用过很多解决方案,都在客户严格要求下牺牲的无比惨烈。  POI读word文档还行,写...
  • nodejs动态生成word文档

    千次阅读 2020-07-25 14:19:43
    公司的新人文档要根据角色来生成一样的word文档,但是里面存在大量的重复内容,每次增加删除一个内容需要更新所有的文档,维护起来太麻烦,加上本人喜欢用markdown写文档,所以我就研究了一下如何通过模板生成...
  • 基于Web停车场管理系统设计软件程序源码+数据库+WORD毕业设计论文文档. 基于Web停车场管理系统主要用于实现停车场相关信息管理,基本功能包括:系统信息管理模块、车位信息管理模块、IC卡信息管理模块、固定车主...
  • 打印当前页面当word文档中有很多页时,而你只需要打印其中某一页时,这个时候我们可以选择打印当前页面。操作方法:依次点击【文件】--【打印】--【设置】--【打印当前页面】即可。 2.指定范围打印连续页面如果只想...
  • 图片合并,WORD如何将文字与图片合并

    千次阅读 2021-01-12 12:23:49
    WORD如何将文字与图片合并简单!第一种,分别插入文本框和图片,双击图片,设置其版式为"衬于文字下方";在文本框中输入文字后,双击文本框边线,设置其版式为"浮于文字上方",边框颜色为"无",然后随意拖动图片和文本框达到...
  • 打印网页显示不全,求助

    千次阅读 2021-01-13 22:29:21
    可以在windows95/98内更改打印接口设置:依次选择“开e68a84e8a2ad62616964757a686964616f31333431363637始→设置→控制面板→系统→设备管理→端口→打印机端口→驱动程序→更改驱动程序→显示所有设备”,将“ecp...
  • 1.1系统开发背景 3 1.2系统开发意义 4 2 相关技术分析及开发环境介绍 5 2.1系统开发环境 5 2.2系统开发技术简介 5 2.2.1B/S 体系结构 5 2.2.2PHP 简介 5 2.2.3MYSQL 数据库技术简介 6 3 需求分析 7 3.1需求...
  • Word文档使用方法与教程:使用正确的部分和章节标题我们在前面的章节中介绍了预设样式,但是这些样式可用于快速创建章节,子标题和标题页。在“主页”功能区选项卡中找到样式,可以在其中找到许多文本格式设置选项。...
  • 5.该压缩包包含的内容:samples文件夹中包含了多个操作Word文档功能的java代码示例DEMO;lib文件夹下包含了用于在java程序中的Spire.Doc.jar文件,在项目程序中调用接口方法时,需要导入该jar文件;doc文件下包含了...
  • WORD文档里面表格下面太多空白怎么接起来方法一方法二参考地址 方法一 选中该表格后,右键点表格属性,勾选行那里的允许跨页断行。 方法二 可能是由于表格宽度不够引起的,内容被自动隐藏了。可以通过修改行距的方式...
  • 如何处理打印出来的图片很黑的情况当我们在打印图片的时候,发现打印出来的图片很黑的话,应如何处理呢?接下来就由小编来告诉大家。具体如下:1. 第一步,打开电脑并在桌面找到ps图标,双击打开。2. 第二步,打开...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,426
精华内容 6,570
关键字:

word文档背景图片打印不全