每天网上的博客各个领域都会涌现新文章,有时候看到感兴趣的知识就想把某段文字 copy下来 摘录下来,等有时间后慢慢品味
在部分网站上,如果只是复制少量文字,并没有什么不同。但是当我们复制的文字多的话会发现多了一个小尾巴
所谓小尾巴是指在复制文本的最后会多一个作者和出处信息,如下:
···(复制的内容)···
————————————————
版权声明:本文为xxx的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://www.cnblogs.com/rainy-night/
博客园可能并没有这种情况,但是在很多技术论坛、博客都有这样的处理。当我们复制文章内容的时候,往往会自动加上一段文本信息版权
那么如果我们也想实现这样的效果要怎么做呢?
前提:假定所选择的字符串长度大于等于130时带上版权信息
<div id="copy">
<div>示例一:这不是一个 bug,这只是一个未列出来的特性。</div>
<div>
示例二:ES6 是一个泛指,含义是 5.1 版以后的 JavaScript。
ES6 是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。
它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,使之成为企业级开发语言。
</div>
</div>
<script>
var copyEl = document.getElementById('copy');
copyEl.oncopy = function (e) {
if (window.getSelection(0).toString().length >= 130) {
var clipboardData = event.clipboardData || window.clipboardData;
// 阻止默认事件
e.preventDefault();
var copyMsg =
window.getSelection() +
'\r\n————————————————\r\n版权声明:本文为xxx的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。' +
'\r\n原文链接:' + location.href;
// 将处理完的信息添加到剪切板
clipboardData.setData('Text', copyMsg);
// 将处理完的信息添加到剪切板
clipboardData.setData('Text', copyMsg);
}
};
</script>
演示
浏览器兼容性
当复制示例一后可以发现粘贴是正常的;复制示例二则会在末尾携带版权信息
我们直接复制代码,会发现当字数超过一定值时也是会携带版权信息。但是点击“复制代码”的时候可以一键复制区域内的代码,这可以怎么实现呢?
<div>
<pre>
<code id="copyable">// 浮点数相加
function mathMultiply(arg1, arg2) {
var m = 0;
var s1 = arg1.toString();
var s2 = arg2.toString();
try {
m += s1.split('.')[1].length; // 小数相乘,小数点后个数相加
} catch (e) {}
try {
m += s2.split('.')[1].length;
} catch (e) {}
return (
(Number(s1.replace('.', '')) * Number(s2.replace('.', ''))) /
Math.pow(10, m)
);
}<code />
</pre>
<button id="btn">复制代码</button>
</div>
<script>
var btn = document.getElementById('btn');
btn.onclick = function copyCode() {
window.getSelection().removeAllRanges(); // 清除选中的文本
var range = document.createRange();
range.selectNode(document.getElementById('copyable'));
var selection = window.getSelection();
selection.addRange(range); // 添加选中的内容
document.execCommand('copy'); // 执行复制
window.getSelection().removeAllRanges(); // 清除复制选中的文本
alert('代码复制成功');
};
</script>
演示
浏览器兼容性
document.execCommand()因为安全问题已经废弃,不适合长期使用
除了以上实现方式,也可以使用第三方库封装好的函数来实现
文章来自https://www.cnblogs.com/rainy-night/p/16132466.html
者:悦然wordpress建站(悦然建站)
继续分享wordpress建站教程,今天教大家给网站的原创文章添加版权信息,能够在一定程度上降低网站内容被采集的影响。
这里给大家分享3种方法,大家可以根据自己的实际需求选择使用。
wordpress建站使用的主题模板下都存在一个文件——single.php,这个文件就是用来控制文章内容显示的,所以我们需要打开single.php文件,可以在宝塔面板中编辑,或者是通过FTP下载这个文件,然后用记事本编辑。
<?php the_content(); ?>
找到上面这行代码。
<script type="text/javascript">
document.body.oncopy=function(){
event.returnValue=false;
var t=document.selection.createRange().text;
var s="本文来源于<?php bloginfo('name'); ?> <?php echo get_settings('home'); ?> , 原文地址: <?php the_permalink() ?> ";
clipboardData.setData('Text','\r\n'+t+'\r\n'+s+'\r\n');
}
</script>
然后复制上面这段代码,按它添加到刚才的代码下方,最后保存。上面代码中的中文说明可以自行修改。
这段代码实现的效果是:当用户复制或采集您的企业网站内容时,会自动把文章的版本信息复制下来。
wordpress也有很多实现版权说明的插件,下面给大家分享的插件为——wp-display-copyright-master,这个插件有点老的,但功能正常,使用也比较简单。
插件下载地址
链接: https://pan.baidu.com/s/1Bce-dKJhnQATk90aVSnH2g 提取码: ps48
安装好之后直接启用就可以了。
如果你不满足插件默认的版本提示内容,你也可以在插件设置中修改,如上图所示,参考上面的说明调整就可以了。
不管是使用代码还是插件,默认情况下都会给全站的文章都添加版权说明。如果你的企业网站内容全部都是原创的,这样做没有问题,但如果你的企业网站内容也是转载的,那这样做就不是太好,乱用版权申明也可能存在一些隐患哦。
所以我们也可以尝试手动添加版权说明,方法就是自己打字,在你的个别原创文章的开头或结尾添加一段版权说明文字就可以了,这个方法适用于所有网站建设程序,比如你的企业网站建设使用的是H5模板建站系统、或者是DEDECMS、帝国CMS等可以。
如果你使用的是wordpress的古腾堡编辑器,那么也可以配合它的可重用区块使用,这样可以在需要添加版权的直接调用,操作方法如下:
1.先编辑好网站版权申明的内容。
wordpress建站教程:古腾堡可重用区块的使用
2.然后添加上面的可重用区块教程操作就可以了。
小结:以上几种方法大家根据实际情况使用即可,用不上的也没必要强行使用了。大家可以观察悦然wordpress建站官网,虽然我的网站内容基本都是原创,但是我并没有添加版权说明。刚开始的时间我也遇到了一些恶心的抄袭者,但随着网站收录的提高,搜索引擎基本都可以识别出原创出处的,也就是说那些抄袭者对我基本没太多影响。所以做好内容才是最重要的哦。
以上就是今天给大家分享的wordpress建站教程,希望对您有用。
注:部分代码参考作者 skyblue NG 博客修改,部分代码在新的版本不适用,所以作了修改,在3.7上可以正常运行。)
上节谈到如何通过自动查找边缘,获取文档轮廓来进行透视转换的问题,在图像文件比较清晰的情况下,这个转换还是很简单的,但是也存在先天的缺陷,就是实际应用所获得的图像并不是那么好获取文档轮廓,所以我们得另辟蹊径来解决这个问题,方法就是通过人工鼠标选取需要转换的区域来实现。这样可以适用于大多数情况。
整体的思路是这样的:
第一步:需要用到tkinter图形界面,构建一个GUI用于图像导入等操作
第二步:定义鼠标事件,对导入的图像选取ROI区域,这里通过鼠标标注ROI的四个角点坐标
第三步:调用上一节使用到的transform and scan 程序,把scan程序修改成一个函数
第四步:显示结果
看起来也不是很难,当然你得对tkinter有所了解,不过参照文档理解这些代码不难,而且我做了大量的注释,尽量减少代码理解的难度。关键是一定要自己动手验证一下。
马上进入第一步:构建一个GUI窗体
# -*- coding: utf-8 -*- from tkinter import * from tkinter.filedialog import askopenfilename #需要用到文件对话框 import cv2 import numpy as np from tkinter import ttk import win32clipboard as wcld import os from scan_module import wrapped root = Tk() # 创建根窗体 frm1 = Frame(root) # 把frm1加载到根窗体中 frm1.pack(side='top',anchor='e',ipadx=1,ipady=1) # 放置frm1框架的为止 frm2 = Frame(root) # 加载第二个框架到根窗体 frm2.pack(side='top',anchor='w',ipadx=1,ipady=3) root.title("ROI截取") Label(frm1,text="ROI截取 第一版",fg ="gray").pack(side="right") # 在框架1中加载一个标签 ttk.Button(frm2,text="打开文件",command=myopen).pack(side="left",ipadx=8) # 在框架2左边加载一个按钮并赋予按钮事件 ttk.Label(frm2,text=" 坐标:").pack(side="left",ipadx=0) # 在框架2左边再加载一个标签 msg = StringVar() ttk.Entry(frm2,width=60, textvariable = msg).pack(side="left",ipadx=0) # 紧接着在框架2左边再加载一个文本输入框 ttk.Button(frm2,text="复制",command=send_to_clibboard).pack(side="right",ipadx=3) # 在框架2右边加载一个按钮并赋予按钮事件 # 进入消息循环 root.mainloop() # tkinter一般只有执行mainloop()方法才能运行,才能创建窗口
构建完是这个样子的:
第二步:定义按钮 ‘打开文件’ 事件,myopen() 函数
filename = "" def myopen(): global filename,img,ROI # 通过askopenfilename()方法直接获取文档名称 filename = askopenfilename(filetypes=(("Template files", "*.tplate"), ("HTML files", "*.html;*.htm"), ("All files", "*.*") )) print (filename) img = cv2.imread(filename) ROI = img.copy() # setMouseCallback()创建了一个鼠标回调函数,每次在图像上单击鼠标左键再抬起的过程,都会分3次调用鼠标响应函数 # 这里调用的回调函数就是上面定义的on_mouse()函数,当鼠标激活打开的图像时,执行相应的操作。 cv2.namedWindow('src') cv2.setMouseCallback('src', on_mouse) cv2.imshow('src', img) cv2.waitKey(0) cv2.destroyAllWindows() 定义on_mouse() 函数: # -----------------------鼠标操作相关------------------------------------------ lsPointsChoose = [] #选取点的坐标列表 tpPointsChoose = [] pointsCount = 0 #鼠标点击的次数 count = 0 pointsMax = 4 #初始化选取点的数量 def on_mouse(event, x, y, flags, param): global img, point1, point2, count, pointsMax global lsPointsChoose, tpPointsChoose # 存入选择的点 global pointsCount # 对鼠标按下的点计数 global img2, ROI_bymouse_flag img2 = img.copy() # 此行代码保证每次都重新再原图画 避免画多了 if event == cv2.EVENT_LBUTTONDOWN: # 左键点击 pointsCount = pointsCount + 1 print('pointsCount:', pointsCount) point1 = (x, y) print (x, y) # 画出点击的点 cv2.circle(img2, point1, 10, (0, 255, 0), 2) # 将选取的点保存到list列表里 lsPointsChoose.append([x, y]) # 用于转化为array 提取多边形ROI tpPointsChoose.append((x, y)) # 用于画点 # ---------------------------------------------------------------------- # 将鼠标选的点用直线连起来 print(len(tpPointsChoose)) for i in range(len(tpPointsChoose) - 1): print('i', i) cv2.line(img2, tpPointsChoose[i], tpPointsChoose[i + 1], (0, 0, 255), 2) # ----------点击到pointMax时可以提取去绘图---------------- if (pointsCount == pointsMax): # -----------绘制感兴趣区域----------- cv2.line(img2, tpPointsChoose[0], tpPointsChoose[pointsMax-1], (0, 0, 255), 2) # 把多边形封闭,最后一个点和起始点连接 ROI_byMouse() # 调用绘制函数画出感兴趣区域 ROI_bymouse_flag = 1 i = 0 pointsCount = 0 tpPointsChoose = [] lsPointsChoose = [] cv2.imshow('src', img2) # -------------------------右键按下清除轨迹----------------------------- if event == cv2.EVENT_RBUTTONDOWN: # 右键点击 print("right-mouse") pointsCount = 0 tpPointsChoose = [] lsPointsChoose = [] cv2.imshow('src', img2) 再定义ROI_byMouse()函数 def ROI_byMouse(): global src, ROI, ROI_flag, mask2, lsPointsChoose, msg mask = np.zeros(img.shape, np.uint8) #print(lsPointsChoose) msg.set(lsPointsChoose)# 储存选择点坐标的列表到msg变量 #print(msg.get()) pts = np.array([lsPointsChoose], np.int32) # pts是多边形的顶点列表(顶点集) pts = pts.reshape((-1, 1, 2)) #print(pts) # 这里 reshape 的第一个参数为-1, 表明这一维的长度是根据后面的维度的计算出来的。 # OpenCV中需要先将多边形的顶点坐标变成顶点数×1×2维的矩阵,再来绘制 # --------------画多边形--------------------- #mask = cv2.polylines(mask, [pts], True, (255, 255, 255)) # -------------填充多边形--------------------- mask2 = cv2.fillPoly(mask, [pts], (255, 255, 255)) #cv2.imshow('mask', mask2) cv2.imwrite('mask.bmp', mask2) ROI = cv2.bitwise_and(mask2, img) wrap_img = wrapped(ROI) cv2.imwrite('ROI.bmp', ROI) cv2.imshow('ROI', ROI) cv2.imshow('wrap_image',wrap_img)
本例中还定义了一个 send_to_clibboard() 复制到剪切板函数用于查看选取的四个角点的坐标,主要用来验证效果,其实可以不用。不过你可以参考。
def send_to_clibboard(): wcld.OpenClipboard() wcld.EmptyClipboard() wcld.SetClipboardData(wcld.CF_UNICODETEXT, msg.get()) # 此处使用.CF_UNICODETEXT方法才能正常解析 wcld.CloseClipboard()
把上一篇的scan.py修改成scan_module()模块用来调用:
# 导入必要的库 #导入上一节构建的模块和函数 from transform import four_point_transform #记得安装scikit-image包,threshold-local函数帮助我们处理黑白图像 from skimage.filters import threshold_local import numpy as np import argparse import cv2 #imutils是一个很实用的图像处理库,比如resize/cropping/rotate等图像基本编辑 import imutils #这个module直接返回转换后的图像,用于其它程序调用 def wrapped(image): # 第一步 # 加载图像并计算新旧图像高度的比例,并拷贝一份,修改大小。 # 为了加快图像处理速度,同时使边缘检测步骤更加准确, # 我们将扫描图像的高度调整为500像素。 # 我们还特别注意跟踪图像的原始高度与新高度的比值, # 这将允许我们对原始图像而不是调整大小的图像执行扫描。 #img = cv2.imread(image) img = image ratio = img.shape[0] / 500.0 orig = img.copy() img = imutils.resize(img, height = 500) # 把图象转化为灰度, 并加模糊处理,然后查找边缘 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) gray = cv2.GaussianBlur(gray, (5, 5), 0) edged = cv2.Canny(gray, 70, 250) # 显示原始图像和检测到的边缘图像,不需要显示 #print("STEP 1: Edge Detection") #cv2.imshow("Image", img) #cv2.imshow("Edged", edged) #cv2.waitKey(0) #cv2.destroyAllWindows() # 第二步 # 在边缘图像的基础上查找轮廓保留最大的一个,并在图像中标识出来 cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE) cnts = imutils.grab_contours(cnts) cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:5] # 循环处理 for c in cnts: # 大致轮廓 peri = cv2.arcLength(c, True) approx = cv2.approxPolyDP(c, 0.02 * peri, True) # 如果查找的大致轮廓有四个角点,即假设为我们需要查找的 if len(approx) == 4: screenCnt = approx break # 显示文档的轮廓在这个模块中不需要显示 #print("STEP 2: Find contours of paper") #cv2.drawContours(img, [screenCnt], -1, (0, 255, 0), 2) #cv2.imshow("Outline", img) #cv2.waitKey(0) #cv2.destroyAllWindows() # 第三步 # 应用四点转换生成鸟瞰图 warped = four_point_transform(orig, screenCnt.reshape(4, 2) * ratio) # 把变形的图像转化成灰度 warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY) T = threshold_local(warped, 11, offset = 10, method = "gaussian") warped = (warped > T).astype("uint8") * 255 return warped
该函数返回转换后的图像。
好了,我们测试一下效果
查看一下视频,演示测试过程:
效果非常好。赶紧动起手来,设计一个属于自己的文档扫描仪吧。下一次尝试一下OCR,文本识别和输出。这个比较有挑战。
*请认真填写需求信息,我们会在24小时内与您取得联系。