图片展示 [ Numpy 处理, Matplotlib 展示 ] 
                                                    
                        
                    
                    
  
                    
                    文件建立日期: 2020/03/14
最后修订日期: 2020/04/05 内容格式调整
相关软件信息: 
| Win10 | Python 3.7.6 | Requests 2.23.0 | Matplotlib 3.2.0 | Numpy 1.18.1 | Pillow 7.0.0 | 
说明: 本文请随意引用或更改, 只须标示出处及作者, 作者不保证内容絶对正确无误, 如造成任何后果, 请自行负责.
标题: 图片展示 [ Numpy处理, Matplotlib展示 ]
PIL (Pillow) 可以用来作图片的处理, 因为要处理的不是静态的图片, 也不太会动到图片的内容, 再加上对Numpy有点生疏, 因此借由Numpy来作整个片的分割处理, 让自己再更深入了解Numpy的使用.
- 目标 - 以各种方式来呈现一张图片
- 方式有很多, 目前只提供以下几种- 亮度變化
- 卷动式或拖动式
- 圆形展示
- 方形展示
- 随机展式
 
- 全部图片的处理只能使Numpy (偶尔会有到list)
 
- 展示 

- 代码及说明 - 相关库的导入
 
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from time import sleep
import random
import requests
from io import BytesIO- 图片由黑到显示 - 数组中的值 (也就是R, G B三色) 按各点颜色的比例从 (0, 0, 0) 到 该点的 (R, G, B), 这样只会改变亮度, 不会改变色. 
def black_to_show(array, interval, mode=0):
    for i in range(interval, -1, -1):
        yield array-array*i/interval- 以方形的方式, 显示图片, 共有8种模式, 主要是依照每个点的索引值来作方形的判断, 再以boolean值来作为图片的数组索引. 函数的内容虽长, 但8种模式的内容大同小异.
def box(array, interval, mode):
    h, w = array.shape[0], array.shape[1]
    half = int(interval/2)
    y0 = np.linspace(0, array.shape[0], interval)
    x0 = np.linspace(0, array.shape[1], interval)
    filter = np.indices(array.shape[0:2])
    im_blank = np.full(array.shape, 255, dtype=np.float)
    if mode == 0:
        for x, y in zip(x0, y0):
            check = np.logical_and(filter[0]<=y, filter[1]<=x)
            im_blank[check] = array[check]
            yield im_blank
    elif mode == 1:
        for x, y in zip(x0[::-1], y0[::-1]):
            check = np.logical_and(filter[0]>=y, filter[1]>=x)
            im_blank[check] = array[check]
            yield im_blank
    elif mode == 2:
        for x, y in zip(x0, y0[::-1]):
            check = np.logical_and(filter[0]>=y, filter[1]<=x)
            im_blank[check] = array[check]
            yield im_blank
    elif mode == 3:
        for x, y in zip(x0[::-1], y0):
            check = np.logical_and(filter[0]<=y, filter[1]>=x)
            im_blank[check] = array[check]
            yield im_blank
    elif mode == 4:
        for x, y in zip(x0[half:], y0[half:]):
            check = np.logical_and(
                np.logical_and(h-y<=filter[0], filter[0]<=y),
                np.logical_and(w-x<=filter[1], filter[1]<=x))
            im_blank[check] = array[check]
            yield im_blank
    elif mode == 5:
        for x, y in zip(x0[half:], y0[half:]):
            check = np.logical_or(
                np.logical_and(h-y<=filter[0], filter[0]<=y),
                np.logical_and(w-x<=filter[1], filter[1]<=x))
            im_blank[check] = array[check]
            yield im_blank
    elif mode == 6:
        for x, y in zip(x0[::-1][:half], y0[::-1][:half]):
            check = np.logical_or(
                np.logical_or(filter[0]>=y, filter[0]<=h-y),
                np.logical_or(filter[1]>=x, filter[1]<=w-x))
            im_blank[check] = array[check]
            yield im_blank
    elif mode == 7:
        for x, y in zip(x0[::-1][:half], y0[::-1][:half]):
            check = np.logical_and(
                np.logical_or(filter[0]>=y, filter[0]<=h-y),
                np.logical_or(filter[1]>=x, filter[1]<=w-x))
            im_blank[check] = array[check]
            yield im_blank- 圆形展示, 分为由外向内或由内向外两种. 处理方式以各点至中心点的距离作判断, 预先计算所有点的距离, 再以boolean数组作为图片数组的索引.
def circle(array, interval, mode=0):
    h, w = array.shape[0]/2, array.shape[1]/2
    value = (((np.arange(array.shape[0])-h)**2)[:, None] +
              (np.arange(array.shape[1])-w)**2)
    m = np.max(value)
    radius = np.linspace(0, m, interval)
    im_blank = np.full(array.shape, 255, dtype=np.float)
    if mode == 0:
        for r in radius:
            im_blank[value<=r,:] = im_np[value<=r,:]
            yield im_blank
    else:
        for r in radius[::-1]:
            im_blank[value>=r,:] = im_np[value>=r,:]
            yield im_blank- 分块随机显示, 简单的图片子数组替换
def random_block(array, interval, mode=0):
    im_blank = np.full(array.shape, 255, dtype=np.float)
    y = np.linspace(0, array.shape[0], interval+1).astype(np.int)
    x = np.linspace(0, array.shape[1], interval+1).astype(np.int)
    where = [(i, j) for i in range(interval) for j in range(interval)]
    np.random.shuffle(where)
    for i, j in where:
        im_blank[y[j]:y[j+1], x[i]:x[i+1]] = array[y[j]:y[j+1], x[i]:x[i+1]]
        yield im_blank- 卷动式的图片展示, 这里也有八种方式, 四个方向 (上, 下, 左, 右), 以及拖动或显示. 这部份更简单了, 就只是图片的子数组代入.
def scroll(array, interval, mode=0):
    im_blank = np.full(array.shape, 255, dtype=np.float)
    if mode < 4:
        for i in np.linspace(1, array.shape[1]-1, interval):
            if mode == 0:
                im_blank[:, :int(i)] = array[:, :int(i)]
            elif mode == 1:
                im_blank[:, :int(i)] = array[:, -int(i):]
            elif mode == 2:
                im_blank[:, -int(i):] = array[:, :int(i)]
            elif mode == 3:
                im_blank[:, -int(i):] = array[:, -int(i):]
            yield im_blank
    else:
        for i in np.linspace(1, array.shape[0]-1, interval):
            if mode == 4:
                im_blank[:int(i)] = array[:int(i)]
            elif mode == 5:
                im_blank[:int(i)] = array[-int(i):]
            elif mode == 6:
                im_blank[-int(i):] = array[:int(i)]
            elif mode == 7:
                im_blank[-int(i):] = array[-int(i):]
            yield im_blank- 图片由白到显示 - 数组中的值 (也就是R, G B三色) 按各点颜色的比例从 (255, 255, 255) 到 该点的 (R, G, B), 这样只会改变亮度, 不会改变色. 
def white_to_show(array, interval, mode=0):
    for i in range(interval, -1, -1):
        yield array+i*(255 - array)/interval- 显示函数 - 调用相关的函数, 设定间隔及模式, 因为有时间的关系, 所以各函数都采用 yield 来迭代输出, Matplot 中的 set_data 可以不用多作已画图像的删除, draw_idle 函数用来更新, pause 用来暂停以更新图片. 
def show(func, array, interval, mode=0):
    for data in func(array, interval, mode):
        im_plt.set_data(np.clip(data.astype(int), 0, 255))
        fig.canvas.draw_idle()
        plt.pause(0.001)- 图片的加载 - 为免图片文件需另外存在, 直接从网页上下载一张图片, 供全程使用. 
url = 'https://p2.bahamut.com.tw/WIKI/82/00365182.JPG'
response = requests.get(url)
im = Image.open(BytesIO(response.content))
im_np = np.array(im, dtype=np.float)- Matplotlib 初使化, 主要还是隐藏坐标轴
fig,ax = plt.subplots(1,1)
ax.get_xaxis().set_visible(False)
ax.get_yaxis().set_visible(False)
im_plt = ax.imshow(np.full(im_np.shape, 255))- 显示各函数的展示功能
show(white_to_show, im_np, 10)
show(black_to_show, im_np, 10)
for mode in range(8):
    show(scroll, im_np, 10, mode=mode)
show(random_block, im_np, 5)
show(circle, im_np, 20, mode=0)
show(circle, im_np, 20, mode=1)
for mode in range(4, 8):
    show(box, im_np, 20, mode=mode)- 关闭绘图接口
plt.close()本作品采用《CC 协议》,转载必须注明作者和本文链接
 
           Jason990420 的个人博客
 Jason990420 的个人博客
         
           
           关于 LearnKu
                关于 LearnKu
               
                     
                     
                     粤公网安备 44030502004330号
 粤公网安备 44030502004330号