简介Photoshop基础简答题整理面向正在学习计算机图形图像处理、准备课程考试或技能认证的读者也可作为教师出题参考。内容覆盖矢量图与位图的特点、路径的理解、蒙板的类型与应用、图像选择与处理流程、计算机图形和图像概念的辨析、CMYK与RGB色彩模式区别、羽化原理及实现、图层合并的三种命令等核心考点每题均给出条理清晰、可直接背诵的参考答案能帮助读者快速建立知识框架并查漏补缺。资源为单个PDF文档共1个文件文件大小仅127KB轻巧便捷适合在手机或电脑上随时打开阅读作为考前冲刺或碎片化复习的随身资料。目前已有51人浏览学习。如果你需要一份PS简答题标准答案这份整理可直接参考使用。1. 一份带“(2)”的ps简答题PDF先弄清楚它为什么搜不到、转不动说实话这类文件名末尾带着“(2)”的“ps简答题.pdf”十有八九是从网盘或班级群重复下载出来的副本这里的ps基本就是Photoshop的简称不是PostScriptPDF里装的是Photoshop基础概念问答比如什么是图层蒙版、通道有哪几种、色彩模式怎么切换。它最让人头疼的地方不是内容看不懂而是被做成了“能看不能搜”的黑匣子双击能翻页想复制题干却乱码想转word又到处是页眉页脚打印出来还发虚。这篇笔记就围绕“把这份PDF变成能搜索、能改题、能组卷的干净题库”展开适合准备PS考试的同学也适合培训机构拿旧PDF重新做讲义的人。网上那些ps破解版、ps免费安装包压缩包风险很高尽量别碰很多ps全家桶、ps笔刷素材分享包里都夹着这类题库PDF真正值得整理成结构化数据的恰恰是这一份。2. 先分辨PDF是文字版还是图片版三步探测法决定用pdftotext还是OCR2.1 为什么会提不动PDF的文本层与图片层是两回事PDF和Word不一样它不是“一个文档”更像一个排版容器。容器里既可能有真正的文字对象也可能只有一张张位图。判断一份PDF能不能直接提取核心就看它有没有文本层。文字版PDF通常由Word直接打印生成选中文字完全正常图片版PDF多来自扫描仪或拍照整页就是一张图复制出来永远是空的。很多PS简答题PDF其实介于两者之间前半部分转自Word后半部分是扫描补充页这种混合型最坑因为纯文本提取会漏题。先跑一段页面统计脚本把每一页的文本长度和图片数量打印出来这是整个处理流程的地基import fitz doc fitz.open(ps简答题 (2).pdf) for i, page in enumerate(doc, 1): text page.get_text().strip() imgs page.get_images(fullTrue) print(f第{i:3}页 | 文本长度{len(text):5} | 图片数{len(imgs)})逻辑说明enumerate(doc, 1)让页码从1开始get_text()抓取该页的文本层内容strip()之后用长度判断这页有没有文字get_images(fullTrue)返回页面引用的图片对象数量。注意它只查xref引用不会解压整张图几十页的文件几秒就能跑完。跑完脚本把输出对照下面这张表基本能确定这份PDF属于哪一类。页面特征判定类型提取策略文本长度明显大于0图片数少或为0文字版pdftotext直接提取文本长度接近0图片数大于等于1图片版渲染页面后OCR前若干页有文本后面若干页文本为空混合型先提取文本再对空页OCR补缺不要凭阅读器里“看起来是文字”就认定能提取。字体子集不全时页面照样渲染得清清楚楚复制出来却是一堆乱码这也是我每次都要先跑统计、而不是直接双击复制的原因。PDF解析的第一原则就是先看数据再选工具。2.2 文字版优先pdftotext加-layout保住编号缩进判定为文字版后最常见做法不是打开Python慢慢解析而是先用系统里的poppler工具集一把梭。pdftotext是poppler-utils自带的命令行工具Linux和Windows的WSL里都有处理本地PDF零依赖、速度快还不会像某些在线工具那样把文件传出去。题库这类内部资料我一般不出本机处理。pdftotext -layout -enc UTF-8 ps简答题 (2).pdf ps.txt wc -l ps.txt head -n 20 ps.txt逻辑说明-layout是关键参数它按页面原始版式保留空格和换行。对简答题这种“题目编号顶格、答案另起一段”的排版没有-layout时pdftotext会把“1.”和题干挤到同一行后面导致后面切题的正则不好写加上之后每道题的边界基本清晰。-enc UTF-8指定输出编码为UTF-8否则中文在Windows记事本里会变成乱码。跑完之后head看前20行确认题号和答案标记是否完整。如果某个中间页的文本长度突然变成0说明它是扫描图回到2.1的表格走混合型处理。如果你更习惯Python生态用pdfplumber也可以按坐标输出字符但速度比pdftotext慢不少几十页的题库没必要我的习惯是先命令行工具摸底再决定要不要上Python。2.3 图片版兜底渲染300dpi再OCR参数怎么设如果探测结果是大半页面没有文本层那就只能走OCR。做OCR的首要原则是能用库就别用在线网站。PS考题里常出现的“图层”“蒙版”“通道”都是常见中文词本地模型完全能搞定没必要把文件传到别人的服务器上。工具链我一般用PyMuPDF做渲染、Tesseract做识别公司里如果团队是.NET技术栈用Tesseract的C#封装或现成的“C# OCR PDF”方向组件也能达到同样效果思路完全一致先按分辨率渲染再交给识别引擎。import fitz import pytesseract from PIL import Image doc fitz.open(ps简答题 (2).pdf) for i, page in enumerate(doc, 1): # 只处理没有文本层的页有文本层的不动 if len(page.get_text().strip()) 0: continue pix page.get_pixmap(dpi300) pix.save(fpage_{i:03d}.png) img Image.open(fpage_{i:03d}.png) txt pytesseract.image_to_string(img, langchi_simeng, config--psm 6) print(f 第{i}页 ) print(txt)逻辑说明先判断这页有没有文本层有就跳过没有才渲染。dpi300是印刷级清晰度中文小五号字也能识别再往上调600只会让图片变大、识别变慢对简答题这种版面没有明显收益。--psm 6让Tesseract按“整块文本”识别而不是按单行或单字对一整页题干效果最好lang写成chi_simeng是因为题干里混着“Photoshop”“RGB”“Alpha”这类英文词只开中文会把这些词转成拼音或直接丢字。跑完把识别文本和pdftotext的结果按页码拼接就得到覆盖全部页的完整文本。还有一个坑先提一下Tesseract不做deskew遇到歪斜扫描页会识别出一堆乱码。先按角度把图转正再识别比对着参数死磕更高效。数据清洗到这里就算完成了下一章是真正的重头戏把一整块文本切成一道题。3. 把PDF文本切成一道道题编号切题、答案剥离与模糊去重3.1 先摸清题目编号规律再写切题正则拿到完整文本下一步是把一坨文本拆成“一道题加一段答案”的结构。这一步很多人翻车原因是他们一上来就写一个大正则想一次匹配所有题号。实际上PDF排版千奇百怪有的题号是“1.”有的是“2、”有的是“1”还有的写“第1题”。直接写万能正则会误伤题干里出现的数字比如“RGB三通道”里的“3”。常见做法是先写几个候选模式分别数一下命中次数用数据决定用哪个。import re txt open(ps.txt, encodingutf-8).read() candidates [ r(?m)^\s*(\d{1,3})[\.、]\s*, r(?m)^\s*第\s*(\d{1,3})\s*题, ] for i, pat in enumerate(candidates, 1): hits re.findall(pat, txt) print(f模式{i}: 命中{len(hits)}次 示例{hits[:5]})逻辑说明(?m)开启多行模式^才能匹配每一行的开头^\s*允许题号前面有缩进(\d{1,3})限定1到3位数字[\.、]覆盖最常见的三种分隔符。re.findall只返回数字组所以结果是一串题号列表。哪种模式命中次数接近你肉眼数的题目数量就用哪种如果两种都不合理回到文本里看实际排版八成是题号后面跟的是全角空格或制表符把\s*改成[ \t\u3000]*再说。这一步花五分钟看数据比反复试正则省一小时。真正干过PDF解析的人都明白题号格式永远是第一个要摸清的事实而不是第一件要猜的事情。3.2 切题与答案分离按“问/答”标记重组题目结构确定模式后就可以正式切题了。切题的原则是“先找起点再做内容切割”用re.finditer找出所有题号的位置相邻两个题号之间的内容就是一道题的完整文本拿到题目内容后再在内部找“答案/答”标记把题干和答案拆开。import re def clean_headfoot(text): text re.sub(r第\s*\d{1,3}\s*页\s*共\s*\d{1,3}\s*页, , text) text re.sub(rPhotoshop\s*简答题题库, , text) text re.sub(r\n{3,}, \n\n, text) return text.strip() def split_questions(text, pattern): text clean_headfoot(text) matches list(re.finditer(pattern, text)) questions [] for idx, m in enumerate(matches): end matches[idx 1].start() if idx 1 len(matches) else len(text) body text[m.end():end].strip() if not body: continue if re.search(r答案\s*[:], body): q, a re.split(r答案\s*[:], body, maxsplit1) elif re.search(r(?m)^\s*答\s*[:], body): q, a re.split(r(?m)^\s*答\s*[:], body, maxsplit1) else: q, a body, questions.append((m.group(1), q.strip(), a.strip())) return questions逻辑说明clean_headfoot先干掉页码和页眉否则“第1页 共10页”里的“1”会被当成题号。re.finditer返回所有题号的match对象idx 1的start()就是下一题起点刚好作为本道题的结束位置最后一道题用len(text)收尾。答案分离用了两个正则第一种匹配行内“答案”第二种匹配行首“答”两种PDF格式都能覆盖。maxsplit1保证答案正文里如果再出现“答案”二字也不会被二次切开。如果原PDF根本没有答案else分支保留整段当题干答案留空后面组卷时只印题干也不会报错。做完这一步你会得到一个结构化的列表每个元素是(题号, 题干, 答案)这就是后续一切处理的原料。3.3 模糊去重用difflib按题干前20字判重PDF整合自多个来源后经常出现同一道题换了标点、加了空格就重复的情况。精确字符串去重解决不了这种问题用difflib的SequenceMatcher算相似度是性价比最高的方案。题库规模就几十道题完全没必要上向量库。from difflib import SequenceMatcher def is_dup(a, b, threshold0.85): if not a or not b: return False sa, sb a[:20], b[:20] return SequenceMatcher(None, sa, sb).ratio() threshold unique [] for no, q, a in questions: if not any(is_dup(q, old[1]) for old in unique): unique.append((no, q, a))逻辑说明is_dup只比较每题题干的前20个字符因为简答题的题干前20字基本把考点定死了答案区长短不该参与判重SequenceMatcher的ratio()返回0到1的相似度0.85阈值适合这种短文本。阈值太低了会合并掉“图层蒙版的作用”和“图层蒙版的原理”这类容易误判的题太高又漏掉带错别字的重复题。跑完如果发现去重后的题目数明显低于预期把threshold提到0.9再看一遍命中列表确认没有误杀后再批量执行。这里还有个习惯尽量别用去重结果覆盖原始文本先另存一份万一手滑删多了还能有后悔药。3.4 导出CSV与Markdown让“转word”不再依赖PDF编辑器很多同事拿到PDF第一反应是丢进pdf编辑器另存成docx结果页眉页脚、扫描页、答案样式全搅在一起改错一道题要删半天。常见做法其实是先把题库结构化成CSV或Markdown再用Word或WPS打开导出PDF只当数据源用。这样既绕开了pdf编辑器的排版僵局也方便后续按标签抽题。import csv rows [(i, q, a) for i, (no, q, a) in enumerate(unique, 1)] with open(ps_题库.csv, w, newline, encodingutf-8-sig) as f: w csv.writer(f) w.writerow([题号, 题干, 答案]) w.writerows(rows) with open(ps_题库.md, w, encodingutf-8) as f: for i, q, a in rows: f.write(f### {i}. {q}\n\n{a}\n\n)逻辑说明CSV用utf-8-sig编码Excel和WPS双击打开中文不会乱码题号重新自增是因为去重后原始编号可能有断号重新编号方便后续抽题时按序号引用。Markdown文件的好处是通用性极强Typora、VS Code、GitHub都能直接预览也可以复制进Word调整格式。到这里任何一份“ps简答题 (2).pdf”都变成了真正属于你自己的结构化题库下一章讲的是这个过程中最容易反复横跳的坑。4. 避坑记录从打开PDF到组卷打印先排掉这五个坑4.1 坑一能看不能复制复制出来全乱码现象PDF阅读器里选中题干正常CtrlC粘贴到记事本却变成一行乱码或者空白。原因PDF的字体子集只嵌入了字形数据没有写入正确的ToUnicode映射。渲染时可以按字形显示反向查Unicode时却查不到这是PDF里最典型的玄学问题跟你电脑装的是哪一版PS软件没有关系。解决不要继续跟复制较劲直接把这一页按2.3的流程渲染成PNG再OCR。识别结果即使有几个错字也比乱码文本有用如果只有个别页乱码其他页正常就按页码混合处理乱码页走OCR正常页走pdftotext。4.2 坑二混合型PDF漏题前面10题有、后面全消失现象pdftotext提取出的文本只到第10题后面的题人间蒸发题目数量对不上。原因后面几页是扫描生成的位图没有文本层pdftotext压根提取不到内容。这种“前半Word、后半扫描”的混合PDF在培训机构流出的题库里非常常见。解决跑一遍2.1的统计脚本把“文本长度小于设定阈值”的页单独挑出来OCR再按页码顺序把两路输出合并合并主流程示意如下# 假定 text_pages[i] 和 ocr_pages[i] 分别来自 pdftotext 与 OCR 结果 full [] for i, page in enumerate(doc, 1): if len(page.get_text().strip()) 20: full.append(text_pages[i - 1]) else: full.append(ocr_pages[i - 1])逻辑说明合并脚本并不复杂难在阈值设多少。我一般先看统计结果分布文本长度出现明显断层的那个值就是阈值比如大部分页在300字以上、扫描页只有几个字符那就用20当阈值。合并完再检查一次题目数量是否连续绝大多数漏题都能在这一步被拦下来。4.3 坑三导出word后答案跟题干揉在一起现象好不容易转出docx发现每一题的答案都紧跟在题干后面想给学生发一份只有题目的讲义还得手工一段段删。原因原PDF里的“答案”标记在pdftotext提取后缩进丢失变成了题干和答案之间一个普通换行通用pdf编辑器转word时不会智能分拆。解决先按3.2的split_questions把题干和答案拆成两个字段再分别导出。如果发现原PDF的答案标记是“【答案】”之类的变体把正则里的答案\s*[:]扩展成(?:答案|答|【答案】)\s*[:]?再跑一次比在word里手动删快一个数量级。4.4 坑四打印发虚、页边距浪费现象打印图片型PDF字迹发毛边缘像水彩晕开网页另存的PDF打印时多出页眉或者每页底部被切掉一块。原因页面本身是低分辨率位图打印机放大打印时只能插值补点自然发虚。还有一部分PDF来自浏览器“web页面pdf打印”打印区域按网页版式走了不是按纸面版式。解决打印前用2.3的渲染管线把页面重新输出成300dpi的PDF或者先把OCR得到的干净文本重新排版成A4再打印。打印对话框里选“实际大小”而不是“适合页面”背景图形要显示就勾上“打印背景图像”。我自己的教训是打印前永远先看打印预览的第一页和最后一页PDF的坑往往藏在首尾。4.5 坑五文件名带“(2)”是重复下载内容却换了版本现象同一个“ps简答题.pdf”下载了两次浏览器自动命名成“ps简答题 (2).pdf”页数和题号基本一致但个别题的表述和答案完全不同。复习到考前一天才发现拿的是另外一版。原因上传者更新过原文件浏览器自动加了副本序号。你以为只是重复下载实际下到的是新版或旧版文件名完全无法区分。解决拿到文件先记指纹用sha256哈希把版本钉死import hashlib raw open(ps简答题 (2).pdf, rb).read() print(hashlib.sha256(raw).hexdigest()[:16])逻辑说明哈希值前16位足够在笔记里做版本标识。我习惯在整理完题库后把哈希写进题库文件名的前缀例如20250512_3f2a_ps题库.csv最近的哈希比文件名可信得多群里有人发“第19题答案”时先对一下哈希再讨论能省掉一晚上的无效争论。5. 输出端的加分动作给简答题打标签十分钟抽出一套模拟卷5.1 用关键词规则给题干打标签不需要标注人力题库整理干净后下一个高频需求是“按章节复习”或“临时组一套模拟卷”。直接random抽题不够专业因为PS简答题的考点很集中图层、蒙版、通道、滤镜、选区、色彩、历史记录、钢笔工具。常见做法是用关键词规则给每道题打标签先规则跑一轮再人工抽查几条修正基本够用。tags { 图层: [图层, 蒙版, 图层样式], 通道: [通道, Alpha, RGB], 滤镜: [滤镜, 锐化, 模糊], 选区: [选区, 魔棒, 套索, 羽化], 色彩: [色彩, 色相, 饱和度, 明度], } def tag_of(q): hit [name for name, keys in tags.items() if any(k in q for k in keys)] return hit if hit else [基础] for no, q, a in unique: print(f{no}. {q[:20]} - {/.join(tag_of(q))})逻辑说明tag_of返回列表所以一道题同时涉及图层和选区时能带两个标签没有命中关键词的题统一落到“基础”比如“什么是像素”这类概念题。这套规则最大的价值不是分类准确而是可解释——哪个词触发的标签一目了然后面想调整分类改字典即可不用重写逻辑。5.2 固定随机种子抽题让同一题库每次抽出的卷子可复现组卷最怕的是每次跑结果都不一样学生拿到的模拟卷和老师手里的答案对不上。random.seed能让随机序列固定下来这是最简单也最容易被忽略的复现手段。import random from collections import defaultdict random.seed(20250512) buckets defaultdict(list) for no, q, a in unique: for t in tag_of(q): buckets[t].append((no, q, a)) paper [] for t in [图层, 通道, 滤镜, 选区]: pool buckets[t] paper random.sample(pool, min(3, len(pool))) random.shuffle(paper) for idx, (no, q, a) in enumerate(paper, 1): print(f{idx}. {q})逻辑说明random.seed(20250512)是核心同一个种子下random.sample的抽取路径完全相同每次运行生成的模拟卷一模一样方便老师对答案、也方便学生反复练想换一套卷把种子改一个数字就行。min(3, len(pool))防止某个标签下题目数量不足时抛异常少于3题就全取。抽出来的卷子可以按之前的CSV结构输出成“模拟卷.csv”打印时只留题干答案列留在自己手里。验证这套抽题是否健康的方法也很简单换一个种子再生成一份对比两份卷子的重复题数。重合率超过30%说明题库太薄要么补题要么把每个标签抽题数从3降到2。我自己以前拿到这种带“(2)”的PDF上来就丢进pdf编辑器转word打印结果考场上好几道题字迹糊成一片血泪教训之后才养成“先跑统计脚本、再决定流程”的习惯。后来把题库做成结构化数据最大的收益不只是省了一次打印而是这份题库能一直复用换版本、加新题、按章抽卷都是几分钟的事。希望帮到你。本文还有配套的精品资源点击获取