# 圖藏圖
## 前言
這是我在逛CSDN的時候逛到某一篇受到的啟發,但我現在找不到了,抱歉QQ。
主要: 把兩張圖疊放在一起,然後想辦法把目標圖隱藏到另一張圖上面。
然後我就再三節大一資訊課把這個實作出來了~
## 想法
首先兩張圖片的大小需要壓縮成可以放進去的大小,同時不要更改到比例,不然會很怪。
接下來就是要在圖上面放上另外一張圖,最簡單的作法就是每隔幾個像素就放另外一張圖的像素。但如果你實際做過一次,就會發現這樣其實合成出來的圖看得出另外一張照片。
此時我就想起我高中準備特選的時候,有試過在我家透過zmq傳照片給我同學,我們那時候就想要優化一下空間,所以就把他除以32,等解碼的時候乘回來就可以解碼了。
> 不過我測試後是 / 4 , 除以32的圖太難看
(簡單說就是除下去雖然會有餘數的部分會被捨去,但是這樣顯示出來就會很接近 (0,0,0) ~ (32,32,32) 就會很黑) 所以不易觀察。
然後解碼的時候肯定也要知道解碼的圖片大小,所以我在前面的幾個像素放上這些資訊,等解碼的時候再去把他抓下來即可。
> 哦對了,記得存檔是 png 我一開始存 jpg 還想說怎麼無法解碼...
## 結果
### 兩張圖合成
可以比較一下合成前,合成後,可以猜一下哪張圖是合成的

:::spoiler 答案
> 左邊
:::
output:

### 圖解析
solve:

> 因為/4的關係,有很多像素都遺漏了,所以看起來會有一點點模糊。
### 其他
放大看,會看出有很多黑點

::: 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 %}