# 圖藏圖 ## 前言 這是我在逛CSDN的時候逛到某一篇受到的啟發,但我現在找不到了,抱歉QQ。 主要: 把兩張圖疊放在一起,然後想辦法把目標圖隱藏到另一張圖上面。 然後我就再三節大一資訊課把這個實作出來了~ ## 想法 首先兩張圖片的大小需要壓縮成可以放進去的大小,同時不要更改到比例,不然會很怪。 接下來就是要在圖上面放上另外一張圖,最簡單的作法就是每隔幾個像素就放另外一張圖的像素。但如果你實際做過一次,就會發現這樣其實合成出來的圖看得出另外一張照片。 此時我就想起我高中準備特選的時候,有試過在我家透過zmq傳照片給我同學,我們那時候就想要優化一下空間,所以就把他除以32,等解碼的時候乘回來就可以解碼了。 > 不過我測試後是 / 4 , 除以32的圖太難看 (簡單說就是除下去雖然會有餘數的部分會被捨去,但是這樣顯示出來就會很接近 (0,0,0) ~ (32,32,32) 就會很黑) 所以不易觀察。 然後解碼的時候肯定也要知道解碼的圖片大小,所以我在前面的幾個像素放上這些資訊,等解碼的時候再去把他抓下來即可。 > 哦對了,記得存檔是 png 我一開始存 jpg 還想說怎麼無法解碼... ## 結果 ### 兩張圖合成 可以比較一下合成前,合成後,可以猜一下哪張圖是合成的 ![](https://hackmd.io/_uploads/Sks-CzZlT.png) :::spoiler 答案 > 左邊 ::: output: ![](https://hackmd.io/_uploads/SyVkp83Ja.png) ### 圖解析 solve: ![](https://hackmd.io/_uploads/ByTW6U3kp.png) > 因為/4的關係,有很多像素都遺漏了,所以看起來會有一點點模糊。 ### 其他 放大看,會看出有很多黑點 ![](https://hackmd.io/_uploads/Hkg4pUhya.png) ::: spoiler 程式碼 do.py1 ```python= import cv2 # import numpy as np def set_length (big_img, sml_img, dst_img): big_h, big_w, _ = big_img.shape sml_h, sml_w, _ = sml_img.shape dst_img [0][5][0] = int(sml_h % 256) dst_img [0][5][2] = int(sml_h//256) print(dst_img[0][5][2]) dst_img [0][7][0] = int(sml_w % 256) dst_img [0][7][2] = int(sml_w//256) return dst_img def generate_img2(big_img, sml_img): dst_img = big_img.copy() big_h, big_w, _ = big_img.shape sml_h, sml_w, _ = sml_img.shape stepx = big_w / sml_w stepy = big_h / sml_h for m in range(0, sml_w ,2): for n in range(0, sml_h , 2): map_col = int(m * stepx + 1) map_row = int(n * stepy + 1) if map_col < big_w and map_row < big_h: for k in range(3): dst_img[map_row][map_col][k] = (sml_img[n][m][k] >> 3) # dst_img[map_row, map_col] = sml_img[n, (m>>5)] return dst_img if __name__ == '__main__': big_img = cv2.imread("1.jpg") small_img = cv2.imread('3.png') print("兩張圖片大小分別為:") print(big_img.shape) print(small_img.shape) print("__正在執行圖片合成__") output_img = generate_img2(big_img,small_img) output_img = set_length(big_img, small_img, output_img) cv2.imwrite('output.png',output_img) print("結束合成,圖片以存檔") # cv2.imshow('output',output_img) # cv2.waitKey(0) ``` solve.py1 ```python = import cv2 import numpy as np import math def solve_length(img): big_h, big_w, _ = img.shape sml_h = img[0][5][0] + img[0][5][2] * 256 sml_w = img[0][7][0] + img[0][7][2] * 256 return sml_h, sml_w, big_w / sml_w, big_h / sml_h def sle_img(img, stepx, stepy, sml_h, sml_w): big_h, big_w, c = img.shape t_h = math.ceil(int(big_h / stepy) / 2) t_w = math.ceil(int(big_w / stepx) / 2) print(t_h, t_w) solve_img = np.zeros((t_h, t_w, 3), np.uint8) i, j, check = 0, 0, False for m in range(2, sml_w - 1, 2): for n in range(0, sml_h - 1, 2): map_col = int(m * stepx + 1) map_row = int(n * stepy + 1) if map_col < big_w and map_row < big_h: for k in range(3): solve_img[i][j][k] = img[map_row][map_col][k] << 3 i += 1 i = 0 j += 1 return solve_img if __name__ == '__main__': img = cv2.imread('output.png') print("正在解決圖片") sml_h, sml_w, stepx, stepy = solve_length(img) print("取得解決圖片大小") print(sml_h, sml_w) solve_img = sle_img(img, stepx, stepy, sml_h, sml_w) cv2.imwrite('solve.png', solve_img) print("圖片以存檔") ``` ::: 藏文字 ```python= import cv2 # import numpy as np def set_length (length, dst_img): dst_img [0][5][0] = int(length % 256) dst_img [0][5][2] = int(length//256) return dst_img def generate_img2(big_img, messenge): dst_img = big_img.copy() big_h, big_w, _ = big_img.shape i = 1; j = 1 for t in messenge: unicode = ord(t) dst_img[i][j][0] = unicode % 40 dst_img[i][j][1] = (unicode % (40*40) - dst_img[i][j][0])//40 dst_img[i][j][2] = unicode // (40*40) j = j + 20 if j >= big_w: i = i + 20 j = 1 if i >= big_h: print("你話太多囉,存不完") assert(0) return dst_img if __name__ == '__main__': file_path = "test.txt" messenge = "" try: with open (file_path, 'r', encoding = 'utf-8') as file: messenge = file.read() except: print("沒讀取檔案") print(messenge) big_img = cv2.imread("1.jpg") print("正在把你的話存成圖片:") print(big_img.shape) print("你說話的長度 = %d" % (len(messenge))) print("__正在執行圖片合成__") output_img = generate_img2(big_img,messenge) output_img = set_length(len(messenge), output_img) cv2.imwrite('output.png',output_img) print("結束合成,圖片以存檔") # cv2.imshow('output',output_img) # cv2.waitKey(0) ``` ```python= import cv2 import numpy as np import math def solve_length(img): length = img[0][5][0] + img[0][5][2] * 256 return length def sle_img(img, length): ret_msg = "" i = 1; j = 1 big_h, big_w, _ = img.shape for k in range(length): unicode = img[i][j][0] + 40*img[i][j][1] + 40*40*img[i][j][2] ret_msg = ret_msg + chr(unicode) j = j + 20 if j >= big_w: i = i + 20 j = 1 return ret_msg if __name__ == '__main__': img = cv2.imread('output.png') print("正在解決圖片") length = solve_length(img) print("取得解決文字長度") print(length) solve_msg = sle_img(img, length) print(solve_msg) ``` ###### tags: `實作` {%hackmd /@hipp0/Hippotumuxthem %}