整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          使用Python調(diào)整圖像大小

          使用Python調(diào)整圖像大小

          以說,每一個“使用計算機(jī)的人”都需要在某個時間點調(diào)整圖像的大小。MacOS的預(yù)覽版可以做到,WindowsPowerToys也可以。

          本文使用Python來調(diào)整圖像大小,幸運的是,圖像處理和命令行工具是Python的兩個特長。

          本文旨在向你展示三件事:

          1. 圖像的基本概念。
          2. 用于操作圖像的Python庫。
          3. 你可以在自己的項目中使用本文的代碼。

          我們要構(gòu)建的命令行程序可以一次調(diào)整一個或多個圖像文件的大小。

          創(chuàng)建圖像

          在這個例子中,我們將創(chuàng)建我們自己的圖像,而不是找到一個真正的圖像來操縱。

          為什么?事實上,創(chuàng)造圖像是一個很好的方式來說明一個圖像實際上是什么。這個調(diào)整大小的程序在Instagram上也同樣適用。

          那么,什么是圖像?在Python數(shù)據(jù)術(shù)語中,圖像是int元組的列表。

          image=list[list[tuple[*int, float]]]
          

          NumPy的定義是一個二維形狀數(shù)組 (h, w, 4),其中h表示高的像素數(shù)(上下),w表示寬的像素數(shù)(從左到右)。

          換句話說,圖像是像素列表(行)的列表(整個圖像)。每個像素由3個整數(shù)和1個可選浮點數(shù)組成:紅色通道、綠色通道、藍(lán)色通道、alpha(浮點可選)。紅色、綠色、藍(lán)色通道(RGB)的值從0到255。

          從現(xiàn)在開始,我們將討論沒有alpha通道的彩色圖像,以保持簡單。Alpha是像素的透明度。圖像也只能有一個值從0到255的通道。這就是灰度圖像,也就是黑白圖像。在這里我們使用彩色圖像!

          import matplotlib as plt
          
          pixel: tuple=(200, 100, 150)
          plt.imshow([[list(pixel)]])
          

          用純Python制作圖像

          Python完全能夠創(chuàng)建圖像。要顯示它,我將使用matplotlib庫,你可以使用它安裝:

          pip install matplotlib
          

          創(chuàng)建像素:

          from dataclasses import dataclass
          
          @dataclass
          class Pixel:
            red: int
            green: int
            blue: int
            # alpha: float=1
          
          pixel=Pixel(255,0,0)
          pixel
          # returns: 
          # Pixel(red=255, green=0, blue=0, alpha=1)
          

          創(chuàng)建圖像:

          from __future__ import annotations
          
          from dataclasses import dataclass, astuple
          from itertools import cycle
          from typing import List
          
          import matplotlib.pyplot as plt
          import matplotlib.image as mpimg
          
          
          @dataclass
          class Pixel:
            red: int
            green: int
            blue: int
            # alpha: float=1
          
          
          pixel=Pixel(255,0,0)
          pixel
          
          marigold: Pixel=Pixel(234,162,33)
          red: Pixel=Pixel(255,0,0)
          
          Image=List[List[Pixel]]
          
          
          def create_image(*colors: Pixel, blocksize: int=10, squaresize: int=9) -> Image:
            """ 用可配置的像素塊制作一個正方形圖像(寬度和高度相同).
            Args:
                colors (Pixel): 可迭代的顏色呈現(xiàn)順序的參數(shù)。
                blocksize (int, optional): [description]. 默認(rèn)10.
                squaresize (int, optional): [description]. 默認(rèn)9.
            Returns:
                Image: 一幅漂亮的正方形圖片!
            """
            img: list=[]
            colors=cycle(colors)
            for row in range(squaresize):
              row: list=[]
              for col in range(squaresize):
                color=next(colors) # 設(shè)置顏色
                for _ in range(blocksize):
                  values: list[int]=list(astuple(color))
                  row.append(values)
              [img.append(row) for _ in range(squaresize)] # 創(chuàng)建行高
            return img
          
          
          if __name__=='__main__':
            image=create_image(marigold, red)
            plt.imshow(image)
          

          這就是渲染的圖像。在背后,數(shù)據(jù)是這樣的:

          [[[234, 162, 33],
            [234, 162, 33],
            [234, 162, 33],
            [234, 162, 33],
            [234, 162, 33],
            [234, 162, 33],
            [234, 162, 33],
            [234, 162, 33],
            [234, 162, 33],
            [234, 162, 33],
            [255, 0, 0],
            [255, 0, 0],
            [255, 0, 0],
            [255, 0, 0],
            [255, 0, 0],
            [255, 0, 0],
            [255, 0, 0],
            [255, 0, 0],
            [255, 0, 0],
            [255, 0, 0],
            [234, 162, 33],
            ...
          

          現(xiàn)在我們有了一個圖像,讓我們調(diào)整它的大小!

          在Python中調(diào)整大小

          在Python中編寫調(diào)整圖像大小的算法實際上有很多的工作量。

          在圖像處理算法中有很多內(nèi)容,有些人為此貢獻(xiàn)了十分多的工作。例如重采樣——在縮小后的圖像中使用一個像素來代表周圍的高分辨率像素。圖像處理是一個巨大的話題。如果你想親眼看看,看看Pillow的Image.py,它在路徑path/to/site-packages/PIL中。

          這中間還有一些優(yōu)化,比如抗鋸齒和減少間隙…這里的內(nèi)容非常多。我們是站在巨人的肩膀上,可以用一行代碼來解決我們的問題。

          如果你有興趣了解更多有關(guān)處理圖像時幕后發(fā)生的事情,我鼓勵你更多地查看“機(jī)器視覺”主題!這絕對是一個蓬勃發(fā)展的領(lǐng)域。

          做得足夠好,就會有很多公司愿意為你的計算機(jī)視覺專業(yè)知識付出最高的代價。自動駕駛,IOT,監(jiān)視,你命名它;所有基本上依賴于處理圖片(通常在Python或C++)。

          一個很好的起點是查看scikit image。

          OpenCV

          OpenCV可以用來作圖像處理。他使用C++編寫并移植到了Python

          import cv2
          
          def resize(fp: str, scale: Union[float, int]) -> np.ndarray:
              """ 調(diào)整圖像大小,保持其比例
              Args:
                  fp (str): 圖像文件的路徑參數(shù)
                  scale (Union[float, int]): 百分比作為參數(shù)。如:53
              Returns:
                  image (np.ndarray): 按比例縮小的圖片
              """    
              _scale=lambda dim, s: int(dim * s / 100)
              im: np.ndarray=cv2.imread(fp)
              width, height, channels=im.shape
              new_width: int=_scale(width, scale)
              new_height: int=_scale(height, scale)
              new_dim: tuple=(new_width, new_height)
              return cv2.resize(src=im, dsize=new_dim, interpolation=cv2.INTER_LINEAR)
          

          interpolation參數(shù)的選項是cv2包中提供的flags之一:

          INTER_NEAREST – 近鄰插值
          INTER_LINEAR – 雙線性插值(默認(rèn)使用)
          INTER_AREA – 利用像素區(qū)域關(guān)系重新采樣。它可能是圖像抽取的首選方法。但是當(dāng)圖像被縮放時,它類似于INTER_NEAREST方法。
          INTER_CUBIC – 一個大于4×4像素鄰域的雙三次插值
          INTER_LANCZOS4 – 一個大于8×8像素鄰域的Lanczos插值
          

          返回后:

          resized=resize("checkers.jpg", 50)
          print(resized.shape)
          plt.imshow(resized) # 也可以使用 cv2.imshow("name", image)
          

          它做了我們所期望的。圖像從900像素高,900像素寬,到450×450(仍然有三個顏色通道)。因為Jupyter Lab的matplotlib著色,上面的屏幕截圖看起來不太好。

          Pillow

          pillow庫在Image類上有一個調(diào)整大小的方法。它的參數(shù)是:

          size: (width, height)
          resample: 默認(rèn)為BICUBIC. 重采樣算法需要的參數(shù)。
          box: 默認(rèn)為None。為一個4元組,定義了在參數(shù)(0,0,寬度,高度)內(nèi)工作的圖像矩形。
          reducing_gap: 默認(rèn)為None。重新采樣優(yōu)化算法,使輸出看起來更好。
          

          以下是函數(shù):

          from PIL import Image
          
          def resize(fp: str, scale: Union[float, int]) -> np.ndarray:
              """ 調(diào)整圖像大小,保持其比例
              Args:
                  fp (str): 圖像文件的路徑參數(shù)
                  scale (Union[float, int]): 百分比作為參數(shù)。如:53
              Returns:
                  image (np.ndarray): 按比例縮小的圖片
              """
              _scale=lambda dim, s: int(dim * s / 100)
              im=Image.open(fp)
              width, height=im.size
              new_width: int=_scale(width, scale)
              new_height: int=_scale(height, scale)
              new_dim: tuple=(new_width, new_height)
              return im.resize(new_dim)
          

          使用Pillow 的函數(shù)與OpenCV非常相似。唯一的區(qū)別是PIL.Image.Image類具有用于訪問圖像(寬度、高度)的屬性大小。

          結(jié)果是:

          resized=resize("checkers.jpg", 30.5)
          print(resized.size)
          resized.show("resized image", resized)
          

          請注意show方法如何打開操作系統(tǒng)的默認(rèn)程序以查看圖像的文件類型。

          創(chuàng)建命令行程序

          現(xiàn)在我們有了一個調(diào)整圖像大小的函數(shù),現(xiàn)在是時候讓它有一個運行調(diào)整大小的用戶界面了。

          調(diào)整一個圖像的大小是可以的。但我們希望能夠批量處理圖像。

          我們將要構(gòu)建的接口將是最簡單的接口:命令行實用程序。

          Pallets項目是Flask背后的天才社區(qū),是一個Jinja模板引擎:Click(https://click.palletsprojects.com/en/7.x/。)

          pip install click
          

          Click是一個用于制作命令行程序的庫。這比使用普通的argparse或在if __name__=='__main__':中啟動一些if-then邏輯要好得多。所以,我們將使用Click來裝飾我們的圖像調(diào)整器。

          下面是從命令行調(diào)整圖像大小的完整腳本!

          """ resize.py
          """
          
          from __future__ import annotations
          import os
          import glob
          from pathlib import Path
          import sys
          
          import click
          from PIL import Image
          
          
          """
          文檔:
              https://pillow.readthedocs.io/en/5.1.x/handbook/image-file-formats.html
          """
          SUPPORTED_FILE_TYPES: list[str]=[".jpg", ".png"]
          
          
          def name_file(fp: Path, suffix) -> str:
              return f"{fp.stem}{suffix}{fp.suffix}"
          
          
          def resize(fp: str, scale: Union[float, int]) -> Image:
              """ 調(diào)整圖像大小,保持其比例
              Args:
                  fp (str): 圖像文件的路徑參數(shù)
                  scale (Union[float, int]): 百分比作為參數(shù)。如:53
              Returns:
                  image (np.ndarray): 按比例縮小的圖片
              """
              _scale=lambda dim, s: int(dim * s / 100)
              im: PIL.Image.Image=Image.open(fp)
              width, height=im.size
              new_width: int=_scale(width, scale)
              new_height: int=_scale(height, scale)
              new_dim: tuple=(new_width, new_height)
              return im.resize(new_dim)
          
          
          @click.command()
          @click.option("-p", "--pattern")
          @click.option("-s", "--scale", default=50, help="Percent as whole number to scale. eg. 40")
          @click.option("-q", "--quiet", default=False, is_flag=True, help="Suppresses stdout.")
          def main(pattern: str, scale: int, quiet: bool):
              for image in (images :=Path().glob(pattern)):
                  if image.suffix not in SUPPORTED_FILE_TYPES:
                      continue
                  im=resize(image, scale)
                  nw, nh=im.size
                  suffix: str=f"_{scale}_{nw}x{nh}"
                  resize_name: str=name_file(image, suffix)
                  _dir: Path=image.absolute().parent
                  im.save(_dir / resize_name)
                  if not quiet:
                      print(
                          f"resized image saved to {resize_name}.")
              if images==[]:
                  print(f"No images found at search pattern '{pattern}'.")
                  return
          
          
          if __name__=='__main__':
              main()
          

          命令行程序從入口點函數(shù)main運行。參數(shù)通過傳遞給click.option選項:

          • pattern采用字符串形式來定位與腳本運行的目錄相關(guān)的一個或多個圖像。--pattern="../catpics/*.png將向上一級查找catpics文件夾,并返回該文件夾中具有.png圖像擴(kuò)展名的所有文件。
          • scale接受一個數(shù)字、浮點或整數(shù),并將其傳遞給resize函數(shù)。這個腳本很簡單,沒有數(shù)據(jù)驗證。如果你添加到代碼中,檢查比例是一個介于5和99之間的數(shù)字(合理的縮小比例參數(shù))。你可以通過-s "chicken nuggets"進(jìn)行設(shè)置。
          • 如果不希望在程序運行時將文本輸出到標(biāo)準(zhǔn)流,則quiet是一個選項參數(shù)。

          從命令行運行程序:

          python resize.py -s 35 -p "./*jpg"
          

          結(jié)果:

          $ py resize.py -p "checkers.jpg" -s 90
          resized image saved to checkers_90_810x810.jpg.
          

          正在檢查文件夾:

          $ ls -lh checkers*
          -rw-r--r-- 1 nicho 197609 362K Aug 15 13:13 checkers.jpg
          -rw-r--r-- 1 nicho 197609 231K Aug 15 23:56 checkers_90_810x810.jpg
          

          不錯!所以程序縮小了圖像,給了它一個描述性的標(biāo)簽,我們可以看到文件大小從362KB到231KB!

          為了查看程序同時處理多個文件,我們將再次運行它:

          $ py resize.py --pattern="checkers*" --scale=20
          resized image saved to checkers_20_180x180.jpg.
          resized image saved to checkers_90_810x810_20_162x162.jpg.
          

          文件系統(tǒng)輸出:

          $ ll -h checkers*
          -rw-r--r-- 1 nicho 197609 362K Aug 15 13:13 checkers.jpg
          -rw-r--r-- 1 nicho 197609 1.8K Aug 16 00:23 checkers_20_180x180.jpg
          -rw-r--r-- 1 nicho 197609 231K Aug 15 23:56 checkers_90_810x810.jpg
          -rw-r--r-- 1 nicho 197609 1.8K Aug 16 00:23 checkers_90_810x810_20_162x162.jpg
          

          只要匹配到了模式,遞歸可以處理任意數(shù)量的圖像。

          Click

          Click 是一個神奇的工具。它可以包裝一個函數(shù)并在一個模塊中以“正常的方式”從一個if __name__=='__main__'語句運行。(實際上,它甚至不需要這樣做;你只需定義和裝飾要運行的函數(shù)即可),但它真正的亮點在于將腳本作為包安裝。

          這是通過Python附帶的setuptools庫完成的。

          這是我的setup.py.

          from setuptools import setup
          
          setup(
              name='resize',
              version='0.0.1',
              py_modules=['resize'],
              install_requires=[
                  'click',
                  'pillow',
              ],
              entry_points='''
                  [console_scripts]
                  resize=resize:main
              '''
          )
          

          使用以下命令生成可執(zhí)行文件/包裝包:

          pip install -e .
          

          現(xiàn)在,你可以在不使用python命令的情況下調(diào)用腳本。另外,如果你將新的可執(zhí)行文件添加到路徑中的文件夾中,你可以從計算機(jī)上的任何位置調(diào)用此程序,如resize -p *jpg -s 75

          結(jié)論

          本教程進(jìn)行了大量的研究:

          • 首先介紹了一些用于圖像處理的第三方Python庫。
          • 然后使用Python從頭構(gòu)建一個圖像,以進(jìn)一步了解圖像的實際含義。
          • 然后,選擇其中一個選項,并構(gòu)建一個腳本,在保持圖像比例的同時縮小圖像。
          • 最后,把所有這些放在一個命令行實用程序中,通過click接受可配置的選項。

          請記住,編寫代碼可能需要數(shù)小時或數(shù)天。但它只需幾毫秒就可以運行。你制作的程序不必很大。任何一件能節(jié)省你的時間或讓你產(chǎn)生更多產(chǎn)出的東西,都有可能為你的余生服務(wù)!

          資源

          • click(https://click.palletsprojects.com/en/7.x/)
          • matplotlib(https://matplotlib.org/3.2.0/tutorials/introductory/images.html)
          • opencv(https://docs.opencv.org/4.4.0/)
          • pillow(https://pillow.readthedocs.io/en/stable/)
          • scikit-image(https://scikit-image.org/)

          作放大鏡,首先必須要掌握常見的六大尺寸值。如果這六個值不太熟悉的話,可能有點吃力,不過下圖已經(jīng)分析的很清楚了,應(yīng)該能看懂。需要注意的一點是,除了鼠標(biāo)位置是按照窗口來進(jìn)行定位的,如圖綠色畫線,其他四項尺寸值是按照父元素——子元素關(guān)系來計算尺寸,如body和div1,div1和div2 。

          offsetLeftstyle.left主要有三點不同:

          現(xiàn)在來分析:當(dāng)放大鏡(鼠標(biāo))在小圖片上移動 x 距離時,大圖片移動的距離Y是多少呢?

          其實根據(jù) 等比 關(guān)系,有圖中的關(guān)系:

          下圖中關(guān)系式,其實就是由核心公式轉(zhuǎn)化而來:X/?=B/D=A/C.

          (為了方便,只討論單方向橫軸方向距離)

          X:放大鏡向左移動的距離;

          ?:大圖片向右(反方向)移動的距離;

          A:放大鏡的寬;

          B:小容器的寬,為了兼容,實際為mark的寬,不過與小容器寬相等的;

          C:大容器的寬;

          D:大圖片的寬;

          圖中數(shù)字代表距離,則x的值應(yīng)該如下計算:

          上面就是放大鏡核心原理。明白了原理后,對于放大鏡的移動范圍,瀏覽器的兼容性等細(xì)節(jié)再進(jìn)行優(yōu)化可以咯。

          代碼還是要貼上來的:

          <!doctype html>
          <html>
          <head>
           <meta charset="UTF-8">
           <title>放大鏡</title>
           <style>
           * {
           margin: 0;
           padding: 0
           }
           // 最外層,包裹所有元素
           #demo {
           display: block;
           width: 400px;
           height: 255px;
           margin: 50px;
           position: relative;
           border: 1px solid #ccc;
           }
           // 小容器
           #small-box {
           position: relative;
           z-index: 1;
           }
           // 放大鏡
           #float-box {
           display: none;
           width: 160px;
           height: 120px;
           position: absolute;
           background: #ffffcc;
           border: 1px solid #ccc;
           filter: alpha(opacity=50);
           opacity: 0.5;
           }
           // 為了兼容IE,把添加在小圖片的特性全部移到mark
           #mark {
           position: absolute;
           display: block;
           width: 400px;
           height: 255px;
           background-color: #fff;
           filter: alpha(opacity=0);
           opacity: 0;
           z-index: 10;
           }
           // 大容器
           #big-box {
           display: none;
           position: absolute;
           top: 0;
           left: 460px;
           width: 400px;
           height: 300px;
           overflow: hidden;
           border: 1px solid #ccc;
           z-index: 1;
           ;
           }
           // 大圖片
           #big-box img {
           position: absolute;
           z-index: 5
           }
           </style>
           <script>
           //頁面加載完畢后執(zhí)行
           window.onload=function() {
           var objDemo=document.getElementById("demo");
           var objSmallBox=document.getElementById("small-box");
           var objMark=document.getElementById("mark");
           var objFloatBox=document.getElementById("float-box");
           var objBigBox=document.getElementById("big-box");
           var objBigBoxImage=objBigBox.getElementsByTagName("img")[0];
           // 鼠標(biāo)移入時觸發(fā)的事件
           objMark.onmouseover=function() {
           objFloatBox.style.display="block"
           objBigBox.style.display="block"
           }
           // 鼠標(biāo)離開時觸發(fā)的事件
           objMark.onmouseout=function() {
           objFloatBox.style.display="none"
           objBigBox.style.display="none"
           }
           // 鼠標(biāo)在小圖片上移動時觸發(fā)的事件
           objMark.onmousemove=function(ev) {
           // 兼容瀏覽器
           var _event=ev || window.event; 
           // 鼠標(biāo)移動的 變化距離
           var left=_event.clientX - objDemo.offsetLeft - objSmallBox.offsetLeft - objFloatBox.offsetWidth / 2;
           var top=_event.clientY - objDemo.offsetTop - objSmallBox.offsetTop - objFloatBox.offsetHeight / 2;
           // 把放大鏡限制在小容器內(nèi)
           if (left < 0) {
           left=0;
           } else if (left > (objMark.offsetWidth - objFloatBox.offsetWidth)) {
           left=objMark.offsetWidth - objFloatBox.offsetWidth;
           }
           if (top < 0) {
           top=0;
           } else if (top > (objMark.offsetHeight - objFloatBox.offsetHeight)) {
           top=objMark.offsetHeight - objFloatBox.offsetHeight;
           }
           //放大鏡跟隨鼠標(biāo)發(fā)生移動后的當(dāng)前位置
           objFloatBox.style.left=left + "px";
           objFloatBox.style.top=top + "px";
           //發(fā)生移動后,產(chǎn)生的 等比例 關(guān)系。
           var percentX=left / (objMark.offsetWidth - objFloatBox.offsetWidth);
           var percentY=top / (objMark.offsetHeight - objFloatBox.offsetHeight);
           //利用等比例關(guān)系計算 大圖片 反向 移動的距離
           objBigBoxImage.style.left=-percentX * (objBigBoxImage.offsetWidth - objBigBox.offsetWidth) + "px";
           objBigBoxImage.style.top=-percentY * (objBigBoxImage.offsetHeight - objBigBox.offsetHeight) + "px";
           }
           }
           </script>
          </head>
          <body>
           <div id="demo">
           <div id="small-box">
           <div id="mark"></div>
           <div id="float-box"></div>
           <img src="macbook-small.jpg" /> // 這張是小圖片。
           </div>
           <div id="big-box">
           <img src="macbook-big.jpg" /> // 這張是大圖片。
           </div>
           </div>
          </body>
          </html>
          

          這張是小圖片,可以下載后置于源碼中使用。

          這張是大圖片,可以下載后置于源碼中使用。

          了點時間寫的,蠻長時間了。個人很喜歡,一段很簡單的代碼,卻能夠?qū)崿F(xiàn)很多功能。(因為代碼文字呈現(xiàn)沒有格式,難以閱讀,以后小編提供的代碼都以截圖方式呈現(xiàn),底部有源碼鏈接)。

          到底多簡單,先來看代碼


          基于jQuery

          基于jQuery

          拖拽實例圖:

          拖拽實例圖

          將代碼剝離,只要寫5行就可以實現(xiàn)拖拽了,是不是很簡單:

          調(diào)用方式


          放大、縮小

          我們給拖拽增加點功能,支持放大、縮小,先看實例圖:

          放大、縮小

          將代碼剝離,原先的代碼保留不變,增加一個綁定事件:

          放大、縮小

          這樣來實現(xiàn)放大、縮小、拖拽是不是很簡單,還能實現(xiàn)很多其他效果,大家慢慢領(lǐng)悟。

          原理分析:

          放大、縮小、拖拽都離不開在網(wǎng)頁上拖動鼠標(biāo),對于前端來說就是 document 的 mousemove,當(dāng)鼠標(biāo)在網(wǎng)頁上移動的時候,無時無刻不在觸發(fā) mousemove 事件,當(dāng)鼠標(biāo)觸發(fā)事件時,什么時候需要執(zhí)行我們特定的操作,這就是我們要做的了。我在 mousemove 中增加了幾個對象來判定是否進(jìn)行操作:

          • move:是否執(zhí)行觸發(fā)操作

          • move_target:操作的元素對象

          • move_target.posix:操作對象的坐標(biāo)

          • call_down:mousemove的時候的回調(diào)函數(shù),傳回來的this指向document

          • call_up:當(dāng)鼠標(biāo)彈起的時候執(zhí)行的回調(diào)函數(shù),傳回來的this指向document

          小提示:

          • 簡單的操作,只需要設(shè)定 move_target 對象,設(shè)置 move_target 的時候不要忘記了 move_target.posix 哦;

          • 復(fù)雜的操作可以通過call_down、call_up進(jìn)行回調(diào)操作,這個時候是可以不用設(shè)置 move_target 對象的

          深入研究

          拖拽和放大、縮小實現(xiàn)了,但是有個問題,當(dāng)我們鼠標(biāo)點擊并滑動的時候,是會選中文本的,為了避免這個問題,大家可以自行百度

          css 阻止文本選中

          css 阻止文本選中

          網(wǎng)頁的放大、縮小、拖拽事件就研究到這里了,小編不再對如何拓展進(jìn)行深入講解,一切靠大家自行研究,權(quán)當(dāng)課后作業(yè)了。~~

          源碼鏈接地址:

          http://orzcss.com/posts/d554a392/


          本文內(nèi)容均屬個人原創(chuàng)作品,轉(zhuǎn)載此文章須附上出處及原文鏈接。

          加關(guān)注,定時推送,互動精彩多,若你有更好的見解,歡迎留言探討!


          主站蜘蛛池模板: 精品爆乳一区二区三区无码av| 另类国产精品一区二区| 亚洲一区二区三区在线| 成人毛片一区二区| 久久国产一区二区三区| 一区二区三区杨幂在线观看| 亚洲日韩AV一区二区三区四区| 精品国产亚洲一区二区在线观看 | 国产无线乱码一区二三区 | 国产成人久久一区二区三区| 成人精品视频一区二区三区不卡 | 一区二区国产精品| 日本一区免费电影| 福利国产微拍广场一区视频在线| 亚欧在线精品免费观看一区| 亚洲视频在线一区| 男女久久久国产一区二区三区| 国产剧情国产精品一区| 亚洲一区二区女搞男| 99久久精品国产免看国产一区| 国产激情一区二区三区成人91| 一区二区三区四区视频在线| 亚洲av午夜精品一区二区三区| 无码人妻精品一区二区三区99不卡| 日韩免费视频一区| 四虎一区二区成人免费影院网址| 国产一区精品视频| 精品国产一区二区三区在线观看 | 亚洲线精品一区二区三区| 人妻无码一区二区三区| 日本中文一区二区三区亚洲| 日韩社区一区二区三区| 国产美女口爆吞精一区二区| 精品日本一区二区三区在线观看| 亚洲日本一区二区三区在线不卡 | 无码人妻精品一区二| 一本大道东京热无码一区| 无码精品一区二区三区在线| 精品一区二区三区在线成人| 一区一区三区产品乱码| 波多野结衣一区在线|