精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

一次單據圖片處理的優化實踐

開發 前端
通過對問題的優化,對以PNG為例的位圖文件結構,和Java中對圖片的基本操作有了漸進式的理解;同時也意識到,日常工作中,通過對業務本身的理解,清楚知道業務的邊界在那里,加上對技術基礎知識的深入理解,才能更細致地針對性做出優化。

1 引言

日常開發中接到這樣的需求,上游系統請求獲取一張A4單據用于倉庫打印及展示,要求PNG圖片格式,但是我們內部得到的單據格式為PDF,需要提取PDF文檔的元素并生成一張PNG圖片。目前已經有不少開源工具實現了這一功能,我們找了網上使用比較多的Apache PDFBox庫來實現功能,如下

// Step 1
PDDocument document = PDDocument.load(content);
PDFRenderer pdfRenderer = new PDFRenderer(document);
// 獲取第1頁PDF文檔
OutputStream os = new ByteArrayOutputStream()
// Step 2
// 為了保證圖片的清晰,這里采用600DPI
BufferedImage image = pdfRenderer.renderImageWithDPI(0, 600);
// Step 3
ImageIO.write(image, "PNG", os);

實際測試時,明顯感覺到卡頓,當一次請求的單據數目較多時尤其嚴重。

經統計,各步驟本機單次運行耗時如下:

pdf 初始化(Step 1):2ms文檔提取及圖片繪制(Step 2):520ms圖片編碼 (Step 3):3823ms

我們發現,最后一句代碼耗時接近4秒,拖累了整體性能。我們要如何優化這樣一個問題呢?

2 BufferedImage介紹

在討論優化問題之前,首先要搞清楚待優化的代碼是做什么的。如上代碼中,使用renderImageWithDPI方法,將文檔元素繪制為BufferedImage對象。

根據描述,BufferedImage用來描述一張圖片,其內部保存了圖片的顏色模型(ColorModel)及像素數據(Raster)。這里簡單解釋就是,內部的Raster實現類中,以某種數據結構(如Byte數組)表示圖片的所有像素數據,而ColorModel實現類,則提供了將每個像素的數據,轉換為對應RGB顏色的方式。

BufferedImage的構造函數中,可以傳入圖片類型來決定使用哪一種ColorModel和Raster。引言的示例中,PDFRender源碼中默認生成的圖片類型為 TYPE_INT_RGB,這種類型表示,每一個像素使用R、G、B三條數據表示,每條數據使用單字節(0~255)表示。

public BufferedImage(int width, int height, int imageType)

需要注意的是,BufferedImage并不表示某一張具體的位圖,而是通過描述每個像素的數據,抽象地表達一張圖片,因此,它可以在內存中通過操作像素數據,直接改變對應圖片。而通過ImageIO.write方法,可以將BufferedImage編碼為具體格式的圖片數據流。此方法會根據formatName選擇該文件格式的編碼器,來對BufferedImage內部的像素數據進行編碼。

public static boolean write(RenderedImage im, String formatName, OutputStream output) throws IOException

以下代碼為BufferedImage的簡單應用

將一個GIF圖片讀取到BufferedImage中,在坐標(10,10)位置打出ABC三個字符,并重新編碼成PNG圖片

BufferedImage image = ImageIO.read(new File("exmaple.gif"));
image.getGraphics().drawString("ABC", 10, 10);
ImageIO.write(image, "PNG", new FileOutputStream("result.png"));

下面這段代碼展示了另一類型的例子,它將圖片中所有的紅色像素點重置成黑色像素點

BufferedImage image = ImageIO.read(new File("example.gif"));
for(int i = 0 ; i < image.getWidth() ; i++) {
   for(int j = 0 ; j < image.getHeight() ; j++) {
       if(image.getRGB(i, j) == Color.RED.getRGB()) {
          image.setRGB(i, j, Color.BLACK.getRGB());
       }
   }
}

如果我們想要取得圖片的數據,可以通過BufferedImage內部的Raster對象獲得。下面的示例,展示了采用了字節數組形式存儲時,取得內部存儲的字節數組的方式。注意,當需要查詢到某一個像素的數據時,需要綜合像素的x,y坐標及ColorModel模型中像素數據的存儲方式來決定數組下標。

BufferedImage im = ImageIO.read(new File("exmaple.gif"));
DataBuffer dataBuffer = im.getRaster().getDataBuffer();
if(dataBuffer instanceof DataBufferByte) {
     DataBufferByte bufferByte = (DataBufferByte) dataBuffer;
     byte[] data = bufferByte.getData();
}

那么,現在我們可以通過看源碼,了解引言的示例代碼的作用。

根據源碼可以了解到,PDFRender對象讀取并識別PDF文檔中的每條語句,利用BufferedImage中的Graphics2D重新畫了一張圖片,并編碼成PNG格式。這里不詳細說了。

3 PNG文件格式淺析

根據上一節的內容可知,把BufferedImage編碼成PNG文件的過程,耗時接近2秒。我們需要簡單了解下編碼PNG文件的過程中,究竟在干什么。

以下參考W3C上對PNG的描述 https://www.w3.org/TR/PNG/#11IHDR ,由于比較復雜,很多東西我也是一知半解,這里僅描述本次優化涉及到的主要內容。

PNG文件可以包含很多數據塊,最主要且必須包含的,是IHDR,IDAT及IEND三個數據塊

我們通過十六進制打開PNG文件,就可以看到具體的數據塊分布

  • IEND
  • IEND為結束標志
  • IHDR

IHDR為文件頭,其后緊跟的字節描述了PNG文件的一些基礎屬性,如寬、高各占4各字節,而Color type和Bit Depth分別表示顏色類型和位深。

1.Colour type顏色類型分為以下幾種:

Greyscale為灰度圖,每個像素用單一的灰度值來描述顏色,灰度值由0(白)到255(黑)逐步加深。

Truecolor即為一般的RGB三通道圖片,R、G、B每一個通道允許用8或16個比特來表示。

Indexed-color為索引色,需要配合調色板PLTE數據塊使用,這里不多做介紹。

后面兩種Greyscale with alpha, truecolor with alpha,顧名思義,即灰度和RGB圖像增加透明度通道

2.Bit Depth(位深度),即每個通道使用多少比特來表示。

比如在一張Colour type=Greyscale中,一個像素由1~255的灰度值來表示,那么這張圖片就是單通道8位深。

根據上表,我們知道位深度于顏色類型是有相關性的。比如Greyscale灰度圖只能支持1,2,4,8,16位深。

3.Compression Method壓縮算法

后面的Compression Method為數據壓縮算法,固定為zlib LZ77算法。該算法通過編碼一定范圍內的重復數據來壓縮整體數據,有興趣的同學可以了解一下,這里不多做介紹了。找了一張網上的解說圖,通過此圖可以大致了解此壓縮具體在做些什么。

LZ77算法可以設置一個壓縮級別參數,參數范圍為0 ~ 9,其中0為不壓縮;1為最快速度,但壓縮率較低;9為壓縮率最高,但速度會相對較慢。

4.Filter Method過濾方法

過濾方法即壓縮前的預處理,主要目的是對于一些顏色變化比較“陡”的圖片,通過一些數據的變換增加像素數據的重復度,從而增加壓縮率。

試想一個場景,一張圖片每一個像素點都是前一個像素顏色的遞增,那么這張圖片每一個像素點都是不同的數值,按照上面的壓縮方法,它將無法被壓縮。而如果我們對它進行預處理,以第一個像素為基準,后面每一個像素點均變換為當前像素與前一個像素的差值,那么這個變換是可逆的,并且會人為創造出大量的重復數據便于壓縮。

具體這些過濾方法為什么可以增加重復數據,由于不涉及此次優化,我也沒有做深入了解。后面可以看到,因為我們業務場景本身的原因,并不需要預處理。

IDAT

IDAT數據塊為真正的圖片像素數據,這部分數據是經過過濾(Filter)及壓縮(Compresson)的,這些方法都有比較成熟的實現,我們也不考慮在這里做任何優化了,因此不多做介紹。

4 優化方案

經過上述內容,針對引言中的問題,我們確定了2個優化方向

  • 業務上,無論怎樣的單據,都是要倉庫打印的,基本都是黑白圖片。PNG的顏色類型使用Truecolor是冗余的,根據上圖中IHDR文件頭表格內容可知,PNG圖片是支持灰度(Greyscale)同時位深為1的,即每個像素點由1比特來表示(0代表白點,1代表黑點)。這樣可以減少PNG文件的體積,以及壓縮生成IDAT塊的時間。
  1. 調整zlib壓縮算法的級別為1,犧牲壓縮率來提高速度

經過查看源碼,當BufferedImage的imageType=TYPE_BYTE_BINARY(二進制)時,JDK中的PNG編碼器會使用灰度的color type及1位深,而我們發現PDFRender類是有參數可控的,當傳入BINARY時,繪制的BufferedImage的類型即為TYPE_BYTE_BINARY。

BufferedImage image = pdfRenderer.renderImageWithDPI(0, 304, ImageType.BINARY);

使用此方法后,ImageIO.write編碼過程耗時減少到150ms左右。

但是這樣改后,我們發現生成的PNG圖像,與原PDF文檔在觀感上相比,有一些發“虛”,如下圖

PDF截圖

PNG截圖

由于TYPE_BYTE_BINARY類型的BufferedImage每個像素只由0,1來表示黑白,很容易想到,這個現象的原因是出在判斷“多灰才算黑”上。

我們來看一下源碼中,BINARY類型BufferedImage的ColorModel,是如何判斷黑白的。BINARY類型的BufferedImage使用的實現類為IndexColorModel, 確定顏色的代碼段如下,最終由pix變量決定顏色的索引號。

int minDist = 256;
int d;
// 計算像素的灰度值
int gray = (int) (red*77 + green*150 + blue*29 + 128)/256;
// 在BINARY類型下,map_size = 2
for (int i = 0; i < map_size; i++) {
 // rgb數組為調色板,每個數組元素表示一個在圖片中可能出現的顏色
 // 在BINARY類型下,rgb只有0x00,0xFE兩個元素
    if (this.rgb[i] == 0x0) {
        // For allgrayopaque colormaps, entries are 0
        // iff they are an invalid color and should be
        // ignored during color searches.
        continue;
    }
    // 分別計算黑&白與當前灰度值的差值
    d = (this.rgb[i] & 0xff) - gray;
    if (d < 0) d = -d;
    // 選擇差值較小的一邊
    if (d < minDist) {
        pix = i;
        if (d == 0) {
            break;
        }
        minDist = d;
    }
}

由以上代碼,在JDK的實現中,通過像素的灰度值更靠近0和255的哪一個,來確定當前像素是黑是白。

這種實現方式對于通用功能來說是合適的,卻不適合我們的業務場景,因為我們生成的圖片都是單據,大部分需要倉庫等場景現場打印,需要優先保證內容的準確性,即不能因為圖片上某一處灰得有點“淺”,就不顯示它。

對于當前業務場景,我們認為簡單地設置一個固定的閾值,來區分灰度值是一個適合的方式。

所以,為解決這個問題,我們設計了2種思路

  1. 繼承實現自己的ColorModel,通過閾值來指定調色板索引號,所有要編碼成PNG的BufferedImage都使用自己實現的ColorModel。
  2. 不使用JDK默認的PNG編碼器,使用其他開源實現,在編碼階段通過判斷BufferedImage像素灰度值是否超過閾值,來決定編入PNG文件的像素數據是黑是白。

從合理性上看,我認為1方案從程序結構角度是更合理的,但是實際應用中,卻選擇了方案2,理由如下

  1. BufferedImage通常不是自己生成的,我們往往控制不了其他開源工具操作生成的BufferedImage使用哪種ColorModel,比如我們的項目里PDF Box,IcePdf, Apache poi等開源包都會提供生成BufferedImage的方法,針對每個開源工具都要重新更改源代碼,生成使用自己實現的ColorModel的BufferedImage,太過于繁瑣了,不具有通用性。
  2. JDK提供的PNG編碼器不能設置壓縮級別

5 實際優化過程

我們通過網上搜到了開源Java實現的PNG編碼器pngencoder作為此業務場景下的編碼器。

<groupId>com.pngencoder</groupId>
<artifactId>pngencoder</artifactId>
<version>0.14.0-SNAPSHOT</version>

但是我們發現一個問題,開源實現的PNG編碼器在編碼BufferedImage時,為了方便整字節進行操作,基本都是只能支持8或16比特的位深的PNG,無法支持我們需要的1比特的位深. 經過分析,這一點可以通過自己開發簡單的代碼實現來補充,因為無論使用幾位深,最終PNG編碼都是針對像素數據整理過后,對整字節的數據進行后續的過濾及壓縮來生成IDAT數據,因此,我們只需要實現對原BufferedImage像素數據的提取并轉換為1比特位深度這一步驟。

因此,我們的需求就是,針對一個BufferedImage,每個像素的灰度值通過與閾值比較大小,映射為一個bit數組,并將bit數組轉換為byte數組。下面是我們借助這個開源工具內部實現的部分代碼:

/**
* 在開源工具原有代碼基礎上,判斷1bit位深時,使用另外的像素數據收集方法
*/
case TYPE_BYTE_GRAY:
    if(bitDepth == 1) {
// 針對灰度圖像,當位深為1的時候走自己實現的數據獲取方法
// RGB圖像也可用類似方式
        getByteOneBitGrey(bufferedImage, yStart, width, heightToStream, consumer);
    } else {
// 原代碼
        getByteGray(bufferedImage, yStart, width, heightToStream, consumer);
    }
    break;

自定義1bit位深取數據方法

/**
* 生成使用1bit位深,Greyscale的PNG的像素數據
* 當IHDR中bit Depth為1時,使用這個方法來生成IDAT的原始數據
* @param image 圖片BufferedImage
* @param yStart 從圖片哪一行開始掃描
* @param width 圖像寬度
* @param heightToStream 待處理的高度
* @param consumer 原始數據塊后續處理函數
*/
static void getByteOneBitGrey(BufferedImage image, int yStart, int width, int heightToStream, AbstractPNGLineConsumer consumer)
        throws IOException {
    // 字節數組的長度
    int rowByteSize = (int) Math.ceil(width / 8.0);
    byte[] currLine = new byte[rowByteSize + 1];
    // BufferedImage Raster像素數據
    byte[] rawBytes = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
    int currLineIndex, bitIndex;
    byte currValue = 0;
    for(int y = 0 ; y < heightToStream ; y++) {
        int start = (yStart + y) * width;
        currLineIndex = 0;
        bitIndex = 0;
        // 這里有一個坑,PNG數據每行要以一個額外的0x00開頭
        currLine[currLineIndex++] = 0;
        for (int i = 0; i < width; i++) {
 // 查到當前像素的灰度值,150為手動設置的閾值,小于150則認為是白色
            byte bitVal = (byte) ((rawBytes[start + i] & 0xFF) < 150 ? 0 : 1);
 // 把每個像素的bit合并到一個byte中
            currValue |= bitVal << (7 - bitIndex++);
            // 當取了8個bit時,將一個完整的byte放入待處理數據
            if (bitIndex == 8) {
                currLine[currLineIndex++] = currValue;
                currValue = 0;
                bitIndex = 0;
            }
        }
  // 如果剩余的bit不夠8個,最后一個byte剩余位為0
        if (bitIndex != 0) {
            currLine[currLineIndex++] = currValue;
        }
// 調用開源工具的方法對數據做后續處理
        consumer.consume(currLine, null);
    }
}

最終用修改后的開源PNG編碼器代替ImageIO.write方法,這里使用壓縮級別為1

byte[] result = new PngEncoder()
.withBufferedImage(image)
.withMultiThreadedCompressionEnabled(false)
// 配置壓縮級別為1
.withCompressionLevel(2)
// 設置位深度為1bit
.withBitDepth(1)
.toBytes();

最終經過優化后測試,和最開始測試時相比,PNG編碼步驟上,無論在耗時還是文件大小上都有很大改善

6 總結

通過對問題的優化,對以PNG為例的位圖文件結構,和Java中對圖片的基本操作有了漸進式的理解;同時也意識到,日常工作中,通過對業務本身的理解,清楚知道業務的邊界在那里,加上對技術基礎知識的深入理解,才能更細致地針對性做出優化。

作者:京東物流 馮凱

來源:京東云開發者社區 自猿其說Tech 轉載請注明來源

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2019-01-21 11:17:13

CPU優化定位

2015-07-17 10:04:33

MKMapView優化

2010-04-01 22:16:21

2020-06-05 08:53:31

接口性能實踐

2011-02-22 09:29:23

jQueryJavaScript

2017-06-12 11:09:56

計數架構數據庫

2019-04-18 14:06:35

MySQL分庫分表數據庫

2020-09-23 06:52:49

代碼方法模式

2022-09-15 10:02:58

測試軟件

2011-06-28 10:41:50

DBA

2020-08-19 11:02:39

系統ssh登錄

2024-09-26 10:41:31

2021-03-18 23:47:18

MySQLselect索引

2021-01-08 13:52:15

Consul微服務服務注冊中心

2020-10-27 10:35:38

優化代碼項目

2018-05-25 14:41:56

Serverless無服務器構造

2017-12-07 12:47:48

Serverless架構基因

2020-10-24 13:50:59

Python編程語言

2021-12-27 10:08:16

Python編程語言

2015-07-14 10:34:42

ViewModel代碼高效
點贊
收藏

51CTO技術棧公眾號

久热成人在线视频| 奇米狠狠一区二区三区| 亚洲激情五月婷婷| 国产日韩欧美一区二区三区四区 | 亚洲日本护士毛茸茸| 91福利视频导航| 国产在线观看黄色| 欧美国产美女| 亚洲精品午夜精品| 免费成人黄色大片| 黄视频网站在线观看| 亚洲国产精品成人综合色在线婷婷 | 精精国产xxxx视频在线野外| 国产欧美日韩在线视频| dy888夜精品国产专区| 中文字幕一区二区人妻电影| 欧美成人69av| 亚洲色图五月天| 免费看91视频| 外国成人毛片| 日韩欧美高清视频| 中文精品一区二区三区| 男同在线观看| 波多野结衣在线一区| 国产区精品在线观看| 中文字幕超碰在线| 伊人久久大香线蕉av超碰演员| 国产亚洲a∨片在线观看| 麻豆免费在线观看视频| 日韩深夜福利网站| 色婷婷综合久久久| 欧美在线一区视频| 最新日本在线观看| 国产精品美女一区二区| 欧美大香线蕉线伊人久久| 国产视频在线一区| 六月丁香婷婷色狠狠久久| 欧美制服第一页| 国产无遮挡aaa片爽爽| 亚洲欧美综合久久久| 中文字幕精品在线视频| 90岁老太婆乱淫| 老汉色老汉首页av亚洲| 日韩欧美国产系列| 日本少妇一区二区三区| 日韩电影精品| 欧美日韩一区二区电影| 免费黄色一级网站| 欧美不卡高清一区二区三区| 一本一道久久a久久精品| 国产精品999视频| av剧情在线观看| 亚洲一区自拍偷拍| 黄色一级大片免费| 2024短剧网剧在线观看| 亚洲精品大片www| 一级性生活视频| 羞羞污视频在线观看| 亚洲精品日韩专区silk| www成人免费| 免费在线观看的电影网站| 夜夜嗨av一区二区三区四季av| 日韩精品福利片午夜免费观看| 成人免费网站在线观看视频| 日韩理论片在线| 一区二区三区四区免费观看| www国产在线观看| 一区二区三区四区蜜桃| 日韩精品在线视频免费观看| av漫画网站在线观看| 精品国产福利在线| 欧美成人黑人猛交| av有声小说一区二区三区| 日本韩国欧美一区| www.夜夜爽| 精品国产乱码久久久久久樱花| 欧美一级理论片| 最新日本中文字幕| 亚洲国产网址| 日韩三级影视基地| 九九九在线视频| 亚洲激情国产| 国产精品电影在线观看| 国产乱人乱偷精品视频a人人澡| 国产精品88av| 欧美成人一区二区在线| 麻豆tv在线| 午夜电影久久久| 中文字幕av专区| 精品国产18久久久久久二百| 亚洲精品ady| 免费一级特黄3大片视频| 9191国语精品高清在线| 97在线观看视频国产| 中文在线观看免费高清| 国产91精品精华液一区二区三区 | 亚洲制服丝袜在线| 亚洲国产精品毛片av不卡在线| 亚洲精品毛片| 日韩精品久久久久| 欧美日韩色视频| 国产视频一区欧美| 91免费看片网站| 神马久久久久| 亚洲精品你懂的| 欧美啪啪免费视频| 性欧美video另类hd尤物| 亚洲国产毛片完整版| 亚洲精品一区二区三区影院忠贞| 欧美影视一区| 国产精品自在线| 亚洲 国产 欧美 日韩| 18欧美乱大交hd1984| 青青草原av在线播放| 麻豆精品一区| 日韩小视频在线观看| 久久久久久久久久免费视频| 国产剧情一区在线| 日韩啊v在线| 韩国精品一区| 日韩免费电影一区| 三级影片在线观看| 日韩国产欧美在线观看| 精品视频免费观看| 欧美xxxbbb| 欧美一区二区三级| 亚洲人做受高潮| 日韩电影在线一区| 久久大香伊蕉在人线观看热2| 欧美卡一卡二| 欧美一卡二卡在线| 一本一本久久a久久| 日韩国产在线观看一区| 欧美在线一二三区| 欧美gv在线| 亚洲国产欧美一区二区三区久久| 免费国产羞羞网站美图| 裸体在线国模精品偷拍| 亚洲一区二区三区色| 亚洲欧洲美洲av| 亚洲国模精品一区| 欧美一级高潮片| 国产v综合v亚洲欧| 日韩a级黄色片| 欧美午夜网站| 色综合91久久精品中文字幕 | 亚洲精品www久久久久久广东| 九九热精彩视频| 国产福利不卡视频| 日韩精品手机在线观看| 秋霞一区二区三区| 欧美国产精品va在线观看| www.成人免费视频| 亚洲国产日韩a在线播放性色| 亚洲熟妇一区二区| 亚洲特级毛片| 精品一区二区国产| 性国裸体高清亚洲| 亚洲人成网在线播放| 国产精品尤物视频| 国产精品激情偷乱一区二区∴| 视频在线观看免费高清| 久久在线视频| 91在线中文字幕| 欧美videosex性极品hd| 日韩免费视频线观看| 亚洲国产精一区二区三区性色| 99久久精品国产麻豆演员表| 欧美成人免费高清视频| 日韩精品dvd| 亚洲最大成人在线| 免费h在线看| 亚洲欧美另类自拍| 中文字幕欧美人妻精品一区蜜臀 | 亚洲精品白浆高清久久久久久| 日韩av在线播| 久久久精品免费免费| 岛国毛片在线播放| 伊人情人综合网| 国产另类自拍| 深夜视频一区二区| 久久久精品国产亚洲| 特黄视频在线观看| 欧美羞羞免费网站| 久草资源在线视频| 26uuu精品一区二区三区四区在线| 黑人粗进入欧美aaaaa| 欧美aa国产视频| 农村寡妇一区二区三区| 91麻豆精品国产91久久久更新资源速度超快| 欧美美女操人视频| 欧美孕妇性xxxⅹ精品hd| 欧美精品成人一区二区三区四区| 国产在线观看成人| 国产精品人人做人人爽人人添| 亚洲av无一区二区三区久久| 久久精品人人做人人爽电影蜜月| 亚洲一区二区在线免费观看| 成人免费在线电影网| 国产精品视频26uuu| 成人在线高清免费| 色偷偷9999www| 五月婷婷综合久久| 91麻豆精品国产91久久久久久久久 | 日本电影一区二区| 国产日产精品一区二区三区四区| 欧美一级做a| 热99精品只有里视频精品| 在线中文字幕视频观看| 国产午夜一区二区| 午夜av免费观看| 日韩精品在线网站| 亚洲天堂网视频| 欧美日韩一区二区在线播放| 丰满少妇高潮久久三区| 国产精品福利一区| 97伦伦午夜电影理伦片| 懂色av一区二区夜夜嗨| 午夜剧场在线免费观看| 日日摸夜夜添夜夜添国产精品| 欧美一区二区视频在线播放| 999久久久国产精品| 欧美精品久久| 免费福利视频一区| 97自拍视频| 国产中文欧美日韩在线| 国产精品中文字幕在线| 欧美粗大gay| 97超碰国产精品女人人人爽| 国内在线免费视频| 欧美成人精品在线视频| 毛片在线看网站| 日韩中文第一页| av在线免费观看网站| 亚洲欧美在线看| 日本黄在线观看| 亚洲精品国产综合区久久久久久久| 午夜久久久久久噜噜噜噜| 91精品久久久久久蜜臀| 97人人爽人人爽人人爽| 欧美日韩和欧美的一区二区| 最近中文字幕av| 欧美日韩视频一区二区| 中文字幕乱码一区二区| 欧美日韩在线三级| 中文字幕在线观看欧美| 欧美性生活一区| 7777久久亚洲中文字幕| 欧美猛男gaygay网站| 国产人妖一区二区| 91精品欧美一区二区三区综合在| 精品人妻av一区二区三区| 日韩三级在线观看| 囯产精品久久久久久| 亚洲国产成人一区| 亚洲三级中文字幕| 亚洲男人的天堂在线| 超碰免费97在线观看| 日韩在线视频播放| 国产素人视频在线观看| 欧美成人精品在线| 岛国av免费在线观看| 欧美做受高潮电影o| 成人黄色免费短视频| 国产精品久久激情| 91精品一区| 国产一区二区久久久| 亚洲免费专区| 亚洲乱码一区二区三区三上悠亚| 香蕉国产精品| 中文字幕无码精品亚洲资源网久久| 国产一区二区三区的电影 | 亚洲天堂一区二区| 国产欧美欧洲在线观看| 欧美欧美在线| 欧美韩国日本精品一区二区三区| 成人免费a**址| 久久久久久久久网| 一区二区日韩免费看| 一区二区在线播放视频| 国产美女主播视频一区| 国产亚洲色婷婷久久99精品91| 国产丝袜在线精品| 国产av无码专区亚洲av毛网站| 亚洲成人一区在线| 无码人妻精品一区二区三区9厂 | 欧美在线视频一区| 日韩免费大片| 久久精品日产第一区二区三区乱码 | 国内偷拍精品视频| 一本到不卡精品视频在线观看| 国产精品久久久久久免费免熟| 亚洲白拍色综合图区| porn视频在线观看| 欧美精品激情在线| 国产亚洲欧美日韩精品一区二区三区 | 一本一道精品欧美中文字幕| 精品福利一二区| 99青草视频在线播放视| 欧美日韩成人在线播放| 日韩不卡免费高清视频| 91在线看网站| 欧美在线色图| 欧美综合在线播放| 国内精品国产三级国产a久久| mm131美女视频| 一区二区三区四区国产精品| 欧美另类高清videos的特点| 亚洲黄页视频免费观看| 成人在线网址| 国产精品久久久久久久久粉嫩av| 国产精品成人自拍| 最近看过的日韩成人| 首页国产欧美久久| 色哟哟无码精品一区二区三区| 国产精品国产a| 亚洲综合久久网| 精品99999| 91精选在线| 91精品在线看| 日韩高清欧美| wwwwxxxx日韩| 久久精品视频在线看| 久久草视频在线| 精品久久99ma| 青青草原av在线| 91老司机在线| 98精品视频| 天堂一区在线观看| 久久久99免费| 五月婷婷亚洲综合| 亚洲精品456在线播放狼人| 激情网站在线| 成人av资源网| 欧美女激情福利| 一个人看的视频www| 亚洲精品v日韩精品| 99久久国产热无码精品免费| 日韩视频欧美视频| 只有精品亚洲| 亚洲国产精品影视| 国精品**一区二区三区在线蜜桃| 亚洲精品国产精品乱码在线观看| 欧美性猛交xxxx黑人交| www.亚洲资源| 国产精品视频久久| 日韩免费特黄一二三区| 欧美美女一级片| 中文字幕一区二| 国产福利第一视频| 欧美精品二区三区四区免费看视频 | 国产盗摄x88av| 欧美精品久久天天躁| 免费a级在线播放| 91在线视频九色| 国内一区二区三区| 91传媒理伦片在线观看| 亚洲成人你懂的| 亚州精品国产精品乱码不99按摩| 欧美性在线视频| 狠狠做深爱婷婷综合一区| 国产精彩免费视频| 国产精品欧美一区二区三区| 亚洲天堂中文字幕在线| 久久影院免费观看| 激情国产一区| 亚洲一区二区三区免费观看| 蜜桃免费网站一区二区三区| 日本视频在线免费| 欧美老女人在线| 99热国产在线| 好吊色欧美一区二区三区视频| 亚洲一卡久久| 一二三四在线观看视频| 7777精品久久久大香线蕉| 欧美人与动牲性行为| 久久久久资源| 美女视频免费一区| 高清国产在线一区| 中国女人久久久| 久久久久久九九九九九| 欧美无砖砖区免费| a毛片在线观看| 精品久久中出| 蜜桃一区二区三区在线观看| 青青草成人免费| 亚洲免费小视频| 91麻豆精品| 久草青青在线观看| 国产精品第一页第二页第三页| 高h放荡受浪受bl| 国产精品va在线| 欧美黄色一级视频| 亚洲av中文无码乱人伦在线视色| 亚洲第一精品福利| 外国电影一区二区| 久久香蕉视频网站| 2021国产精品久久精品| 国产精品女同一区二区| 性欧美xxxx视频在线观看|