冷空气鑫 发表于 2021-7-16 11:31

某验滑块图片还原

最近看到一个一个滑块的图片还原挺有意思的,通过js还原,再用画布画上去.
他的原生js长这样

算法不难看出来 就是把一张图切割成52份(Ge里面包含了切割顺序) 每份宽10px高80px 然后通过getImageData复制原图片的像素 再通过putImageData画进一个新的画布!最开始想着尽量不改变原有代码的情况下,还原用纯jscanvas还原,然后弄了一下午,中途也问过公司的前端,最终放弃.然后就捣鼓这python还原.代码如下:

from PIL import Image
import time
import hashlib

import shutil
class PIG(object):
    def __init__(self):
      ##图片还原的顺序 ,固定不变 除非版本更新
      self.sx=

    def create_dir_not_exist(self,path):
      if not os.path.exists(path):
            os.mkdir(path)

    def get_img(self):
      ###拿到图片还原的坐标 xy
      s=80
      u=10
      self.all=[]
      fori in range(0,52):
            c=self.sx%26*12+1
            # f=k
            if self.sx>25:
                f=80
            else:
                f=0
            tuple=(c, f, u, s)
            self.all.append(tuple)

    def save_jpg(self,path):
      """
      切割图片
      """
      md5 = hashlib.md5(str(time.time()).encode("utf-8")).hexdigest()
      img = Image.open(path)
      path1 = path.split("/")
      path1=path1
      new_path="/".join(path1)+"/"+md5+"/"
      self.create_dir_not_exist(new_path)
      forindex,iin enumerate(self.all):
            q=i
            w=i
            e=i
            r=i
            new_img = img.crop((q,w,q+e,w+r))
            new_img.save(f"{new_path}{index}.jpg")
      return new_path

    def work(self,path):
      """
      传入图片路径 ./images/old/12.jpg
      """
      self.get_img()
      new_path=self.save_jpg(path)
      self.pinjie_image(new_path,0,26,"")
      self.pinjie_image(new_path,26,52,1)
      fin_path=self.finally_img(new_path)
      return fin_path

    def pinjie_image(self,old_path,a,b,c):
      joint = Image.new('RGB', (260, 80))
      for i in range(a,b):
            path=f"{old_path}{i}.jpg"
            img=Image.open(path)
            if i>25:
                loca = ((i - 26) * 10, 0)
            else:
                loca = (i * 10, 0)
            joint.paste(img, loca)
      joint.save(f'{old_path}horizontal{c}.png')



    def finally_img(self,path):
      img1 = Image.open(f"{path}horizontal.png")
      img2 = Image.open(f"{path}horizontal1.png")

      joint = Image.new('RGB', (260, 160))
      loc1, loc2 = (0, 0), (0, 80)

      joint.paste(img2, loc2)
      joint.paste(img1, loc1)
      md5 = hashlib.md5(str(time.time()).encode("utf-8")).hexdigest()

      joint.save(f'images/new/{md5}.png')
      shutil.rmtree(path)
      return f'images/new/{md5}.png'

    def is_px_equal(self, img1, img2, x, y):
      """
      判断两个像素是否相同
      :param img1: 图片1
      :param img2:图片2
      :param x:位置1
      :param y:位置2
      :return:像素是否相同
      """
      pix1 = img1.load()
      pix2 = img2.load()
      threshold = 60

      if abs(pix1 - pix2) < threshold and abs(pix1 - pix2) < threshold and abs(
                        pix1 - pix2) < threshold:
            return True
      else:
            return False

    def get_gap(self, img1, img2):
      """
      获取缺口偏移量
      :param img1: 不带缺口图片
      :param img2: 带缺口图片
      :return:
      """
      left = 0
      for i in range(left, img1.size):
            for j in range(img1.size):
                if not self.is_px_equal(img1, img2, i, j):
                  left = i
                  return left

      return left

if __name__ == '__main__':
    start=PIG()
    path=start.work("images/old/test.jpg")
    path1=start.work("images/old/test1.jpg")
    print(start.get_gap(Image.open(path),Image.open(path1)))
    os.remove(path1)
    os.remove(path)

完美还原,顺便求出了缺口距离

dejavuwl 发表于 2021-7-16 17:17

所以还原的目的纯粹就是为了那张原图吗?
还是就是纯技术爱好?

QingYi. 发表于 2021-7-25 19:14

看着难受


from PIL import Imageimport time
import hashlib

import shutil
class PIG(object):
    def __init__(self):
      ##图片还原的顺序 ,固定不变 除非版本更新
      self.sx=

    def create_dir_not_exist(self,path):
      if not os.path.exists(path):
            os.mkdir(path)

    def get_img(self):
      ###拿到图片还原的坐标 xy
      s=80
      u=10
      self.all=[]
      fori in range(0,52):
            c=self.sx%26*12+1
            # f=k
            if self.sx>25:
                f=80
            else:
                f=0
            tuple=(c, f, u, s)
            self.all.append(tuple)

    def save_jpg(self,path):
      """
      切割图片
      """
      md5 = hashlib.md5(str(time.time()).encode("utf-8")).hexdigest()
      img = Image.open(path)
      path1 = path.split("/")
      path1=path1
      new_path="/".join(path1)+"/"+md5+"/"
      self.create_dir_not_exist(new_path)
      forindex,iin enumerate(self.all):
            q=i
            w=i
            e=i
            r=i
            new_img = img.crop((q,w,q+e,w+r))
            new_img.save(f"{new_path}{index}.jpg")
      return new_path

    def work(self,path):
      """
      传入图片路径 ./images/old/12.jpg
      """
      self.get_img()
      new_path=self.save_jpg(path)
      self.pinjie_image(new_path,0,26,"")
      self.pinjie_image(new_path,26,52,1)
      fin_path=self.finally_img(new_path)
      return fin_path

    def pinjie_image(self,old_path,a,b,c):
      joint = Image.new('RGB', (260, 80))
      for i in range(a,b):
            path=f"{old_path}{i}.jpg"
            img=Image.open(path)
            if i>25:
                loca = ((i - 26) * 10, 0)
            else:
                loca = (i * 10, 0)
            joint.paste(img, loca)
      joint.save(f'{old_path}horizontal{c}.png')



    def finally_img(self,path):
      img1 = Image.open(f"{path}horizontal.png")
      img2 = Image.open(f"{path}horizontal1.png")

      joint = Image.new('RGB', (260, 160))
      loc1, loc2 = (0, 0), (0, 80)

      joint.paste(img2, loc2)
      joint.paste(img1, loc1)
      md5 = hashlib.md5(str(time.time()).encode("utf-8")).hexdigest()

      joint.save(f'images/new/{md5}.png')
      shutil.rmtree(path)
      return f'images/new/{md5}.png'

    def is_px_equal(self, img1, img2, x, y):
      """
      判断两个像素是否相同
      :param img1: 图片1
      :param img2:图片2
      :param x:位置1
      :param y:位置2
      :return:像素是否相同
      """
      pix1 = img1.load()
      pix2 = img2.load()
      threshold = 60

      if abs(pix1 - pix2) < threshold and abs(pix1 - pix2) < threshold and abs(
                        pix1 - pix2) < threshold:
            return True
      else:
            return False

    def get_gap(self, img1, img2):
      """
      获取缺口偏移量
      :param img1: 不带缺口图片
      :param img2: 带缺口图片
      :return:
      """
      left = 0
      for i in range(left, img1.size):
            for j in range(img1.size):
                if not self.is_px_equal(img1, img2, i, j):
                  left = i
                  return left

      return left

if __name__ == '__main__':
    start=PIG()
    path=start.work("images/old/test.jpg")
    path1=start.work("images/old/test1.jpg")
    print(start.get_gap(Image.open(path),Image.open(path1)))
    os.remove(path1)
    os.remove(path)

zhaoshutao123 发表于 2021-7-16 14:25

真的厉害学到了学到了

南宫零 发表于 2021-7-16 15:38

感谢楼主分享..不过我水平不够还没看太懂...

加奈绘 发表于 2021-7-16 16:29

先收藏了,以后慢慢学{:1_918:}

xiaoAmie 发表于 2021-7-16 16:45

感谢分享

叶隽 发表于 2021-7-17 00:00

谢谢,学习到了

有白云的日子。 发表于 2021-7-17 01:07

感谢分享,虽然对我没用{:1_907:}

woaipojie14152 发表于 2021-7-17 01:58

谢谢分享

cool1000 发表于 2021-7-17 07:47

学习学习。
页: [1] 2 3 4
查看完整版本: 某验滑块图片还原