最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

React處理復(fù)雜圖片樣式的方法詳解

 更新時間:2024年04月26日 09:59:39   作者:慕仲卿  
這篇文章主要為大家詳細(xì)介紹了React處理復(fù)雜圖片樣式的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

正如文章題目所示,本文的目的是為了記錄工作中遇到的,在頁面中處理復(fù)雜圖片樣式的解決方案。使用的技術(shù)棧有:

  • web Worker
  • fetch
  • createImageBitmap
  • OffscreenCanvas
  • Blob

之所以稱之為“兜底”方案,是因為下文中提到的方法能夠以像素級別操作圖片。而,如果只是這樣,也沒有什么值得記錄的。但是,本文為了防止這種像素級別的操作對頁面渲染性能造成大的沖擊,結(jié)合 web worker 異步處理,解決了這個問題。

從本文的思路出發(fā),至少可以收獲兩點技術(shù):

  • web worker 的實際使用案例
  • 前端 PS 的基礎(chǔ)知識

下面讓我們開始吧~

本文分為三個小節(jié),第一小節(jié)簡單的介紹上面提到的技術(shù)棧;第二小節(jié)在非工程化 Demo 中演示這個解決方案的流程;第三小節(jié)將此方法分裝成一個 React 組件,以便后面復(fù)用和維護(hù)。

1. 技術(shù)棧介紹

  • Web Worker: Web Worker是瀏覽器提供的一種能在后臺線程中運行JavaScript的技術(shù),它不會阻塞或影響頁面的性能。通過創(chuàng)建一個新的Worker對象,可以將耗時的計算或數(shù)據(jù)處理任務(wù)放在后臺執(zhí)行,從而避免UI線程被長時間占用,提高頁面的響應(yīng)性和用戶體驗。Web Worker通過postMessage和onmessage進(jìn)行主線程和工作線程之間的通信。
  • Fetch: Fetch是一個現(xiàn)代、強(qiáng)大且靈活的網(wǎng)絡(luò)請求API,它提供了一個全局fetch()方法,用于異步獲取網(wǎng)絡(luò)資源。與XMLHttpRequest相比,F(xiàn)etch更加簡潔、高效,且支持Promise模式,使得異步處理更加直觀和方便。Fetch還支持跨域請求、請求和響應(yīng)的攔截、處理HTTP管道等高級功能,是現(xiàn)代Web開發(fā)中網(wǎng)絡(luò)請求的首選方式。
  • createImageBitmap: createImageBitmap是一個用于創(chuàng)建位圖圖像的API,它可以直接從各種圖像源(如Blob、ImageData、ImageBitmap、HTMLCanvasElement等)生成一個高效的位圖。這個API是異步的,不會阻塞主線程,因此非常適合用于處理大量圖像數(shù)據(jù)。生成的ImageBitmap對象可以直接用于Canvas的drawImage方法,極大地提高了圖像渲染的性能。
  • OffscreenCanvas: OffscreenCanvas是HTML5 Canvas API的一個擴(kuò)展,它允許在Web Worker中使用Canvas功能。這意味著圖像處理、渲染等計算密集型任務(wù)可以在不阻塞主線程的情況下進(jìn)行。OffscreenCanvas通過transferControlToOffscreen或getContext('2d', {offscreen: true})等方式創(chuàng)建,并可以在主線程和工作線程之間傳遞,從而實現(xiàn)了真正的后臺渲染。
  • Blob: Blob(Binary Large Object)是一個用于處理二進(jìn)制數(shù)據(jù)的JavaScript對象。它可以存儲大量的二進(jìn)制數(shù)據(jù),并允許通過URL.createObjectURL()方法創(chuàng)建一個指向該數(shù)據(jù)的URL,這個URL可以直接用于img、audio、video等元素的src屬性。Blob常用于處理文件上傳、下載以及圖像、音頻、視頻的動態(tài)生成等場景。此外,Blob還支持切片操作,便于大數(shù)據(jù)的處理和傳輸。

這些知識不能說不常見吧,反正是有點高級的。所以這個解決方案還是有點東西的,你可以用來在面試中吹牛

2. 兜底方案流程圖

本文介紹的解決方案可以用下面的流程圖表示:

在一個空白的文件夾下面創(chuàng)建以下文件

  • index.html
  • worker.js

使用到的代碼如下:

<!DOCTYPE html>
<html>

<head>
  <title>Web Worker Image Processing</title>
</head>

<body>
  <img id="originalImage" src="https://images.pexels.com/photos/12196392/pexels-photo-12196392.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load" alt="Original Image" />
  <img id="processedImage" alt="Processed Image" />

  <script>
    // 創(chuàng)建一個Web Worker實例  
    const worker = new Worker('worker.js');

    // 監(jiān)聽Web Worker的消息  
    worker.onmessage = function (e) {
      const processedImageUrl = e.data;
      
      const _ = document.getElementById('processedImage');
      _.onload = () => {
        worker.terminate();
      }
      _.src = processedImageUrl;
    };

    // 圖片地址,你可以根據(jù)需要修改  
    const imageUrl = 'https://images.pexels.com/photos/12196392/pexels-photo-12196392.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load';

    // 當(dāng)原始圖片加載完成后,向Web Worker發(fā)送消息  
    document.getElementById('originalImage').onload = function () {
      worker.postMessage(imageUrl);
    };  
  </script>
</body>

</html>
// worker.js
// 當(dāng)此Web Worker接收到消息時,會調(diào)用此函數(shù)  
self.onmessage = async function (e) {  
  
  // 從接收到的消息中提取出圖片的URL  
  const imageUrl = e.data;  
  
  try {  
    // 使用fetch API從給定的URL異步獲取圖片資源  
    const response = await fetch(imageUrl);  
  
    // 檢查HTTP響應(yīng)狀態(tài),如果不是200-299之間,則拋出錯誤  
    if (!response.ok) {    
      throw new Error(`HTTP error! status: ${response.status}`);    
    }  
  
    // 將響應(yīng)體轉(zhuǎn)換為Blob對象,這通常用于處理二進(jìn)制數(shù)據(jù)  
    const blob = await response.blob();  
  
    // 使用Blob對象創(chuàng)建一個ImageBitmap,這是一個可以高效繪制到Canvas上的位圖圖像  
    const imgBitmap = createImageBitmap(blob);  
  
    // ImageBitmap對象創(chuàng)建是異步的,所以使用.then()來處理創(chuàng)建成功后的操作  
    imgBitmap.then(function (bitmap) {  
      // 創(chuàng)建一個離屏Canvas,其尺寸與位圖相同  
      const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);  
  
      // 獲取Canvas的2D渲染上下文  
      const ctx = canvas.getContext('2d');  
  
      // 在Canvas上繪制位圖  
      ctx.drawImage(bitmap, 0, 0);  
  
      // 從Canvas上獲取圖像數(shù)據(jù)  
      const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);  
  
      // 獲取圖像數(shù)據(jù)的像素數(shù)組  
      const data = imageData.data;  
  
      // 遍歷每個像素,將其轉(zhuǎn)換為灰度(通過計算RGB通道的平均值,并將其設(shè)置為每個通道的值)  
      for (let i = 0; i < data.length; i += 4) {  
        const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;  
        data[i] = avg; // R  
        data[i + 1] = avg; // G  
        data[i + 2] = avg; // B  
      }  
  
      // 將處理后的圖像數(shù)據(jù)放回Canvas  
      ctx.putImageData(imageData, 0, 0);  
  
      // 將Canvas轉(zhuǎn)換為Blob對象  
      canvas.convertToBlob().then(blob => {  
        // 創(chuàng)建一個表示該Blob對象的URL  
        const newUrl = URL.createObjectURL(blob);  
  
        // 將新的圖像URL發(fā)送回主線程  
        self.postMessage(newUrl);  
      });  
  
    }).catch(e => {  
      // 如果在處理過程中發(fā)生錯誤,則拋出一個新的錯誤(這里可以添加更詳細(xì)的錯誤處理)  
      throw new Error();  
    });  
  
  } catch (e) {  
    // 如果在嘗試獲取或處理圖像時發(fā)生錯誤,則將原始圖像URL發(fā)送回主線程  
    self.postMessage(imageUrl);  
  }   
};

理解上面代碼的邏輯可以結(jié)合代碼注釋和流程圖,在此就不過多贅述了。

完成之后使用 live server 啟動 index.html 可以看到如下效果:

左邊是原圖,而右邊是經(jīng)過 web worker 處理之后的圖像。

在這個示例中,你可以簡單的將 web worker 理解成為 PS。它接受原始圖片的地址,返回處理之后的圖片的地址。

需要注意的是,圖片是二進(jìn)制數(shù)據(jù),所以我們用到了 Blob 將數(shù)據(jù)轉(zhuǎn)成 URL。

3. 封裝成 React 組件

在 React 中使用 web worker 需要一點技巧,請參考我之前的文章: 在react項目中使用web worker的方法 - 掘金 (juejin.cn)

在你的前端工程目錄中創(chuàng)建 src/component/ImageProcessor 目錄,然后創(chuàng)建下面兩個文件:

文件中的代碼如下所示:

// index.js
// 引入React及其相關(guān)hooks
import React, { useEffect, useRef, useState } from 'react';
// 引入Web Worker的腳本
import workerScript from './worker';
// ImageProcessor組件,它接受原始圖片的URL、寬度和高度作為屬性
const ImageProcessor = ({ originSrc, width, height }) => {
  // 使用useState hook來存儲處理后的圖片URL,初始值為原始圖片的URL
  const [src, setSrc] = useState(originSrc);
  // 使用useRef hook來存儲Web Worker的實例
  const workerInstance = useRef(new Worker(workerScript));
  // 使用useEffect hook來處理圖片的URL變化
  useEffect(() => {
    // 當(dāng)原始圖片URL與處理后的圖片URL不相同時,才進(jìn)行處理
    if (originSrc === src) {
      // 設(shè)置Web Worker的onmessage事件處理函數(shù)
      workerInstance.current.onmessage = function (e) {
        // 接收處理后的圖片URL
        const processedImageUrl = e.data;
        // 更新處理后的圖片URL狀態(tài)
        setSrc(processedImageUrl);
      };
      // 向Web Worker發(fā)送原始圖片的完整URL,以便進(jìn)行處理
      workerInstance.current.postMessage(window.location.origin + originSrc);
    }
    // 清除函數(shù),在組件卸載或狀態(tài)變化時終止Web Worker
    return () => {
      workerInstance.current.terminate();
    }
    // 當(dāng)原始圖片URL或處理后的圖片URL發(fā)生變化時,觸發(fā)此hook
  }, [src, originSrc])

  // 圖片加載完成后的事件處理函數(shù)
  const imageLoaded = (event) => {
    // 終止當(dāng)前的Web Worker
    workerInstance.current.terminate();
  };

  // 返回JSX,表示組件的UI
  return (
    <div>
      {/* 當(dāng)原始圖片的URL與處理后的圖片URL不相同時,顯示處理后的圖片 */}
      {originSrc !== src && <img
        style={{
          position: 'absolute',
          left: 0,
          top: 0,
          zIndex: 0,
          width: width ?? '100%',// 使用nullish coalescing操作符來提供默認(rèn)值
          height: height ?? '100%',
          objectFit: 'cover',// 圖片填充方式
        }}
        src={src}// 設(shè)置圖片的URL
        alt="Original Image"http:// 圖片的替代文本
        onLoad={imageLoaded}// 圖片加載完成后的事件處理函數(shù)
      />}
    </div>
  );
};

// 導(dǎo)出ImageProcessor組件
export default ImageProcessor;
// worker.js
// 定義一個workerCode函數(shù),這個函數(shù)將作為Web Worker的代碼  
const workerCode = () => {  
  
  // 使用_self變量來引用全局的self對象,以便在Web Worker內(nèi)部使用  
  // 是用來告訴eslint忽略下一行的代碼檢查,因為這里我們對self進(jìn)行了重新賦值
  // eslint-disable-next-line   
  const _self = self;  
  
  // 當(dāng)Web Worker接收到消息時,會調(diào)用此函數(shù)  
  _self.onmessage = async function (e) {  
    // 從接收到的消息中提取出圖片的URL  
    const imageUrl = e.data;  
  
    try {  
      // 使用fetch API異步地從給定的URL獲取圖片資源  
      const response = await fetch(imageUrl);  
  
      // 檢查HTTP響應(yīng)狀態(tài),如果不是200-299之間,則拋出錯誤  
      if (!response.ok) {  
        throw new Error(`HTTP error! status: ${response.status}`);  
      }  
  
      // 將HTTP響應(yīng)的內(nèi)容轉(zhuǎn)換為Blob對象,這通常用于處理二進(jìn)制數(shù)據(jù)  
      const blob = await response.blob();  
  
      // 使用Blob對象創(chuàng)建一個ImageBitmap,這是一個可以高效繪制到Canvas上的位圖圖像  
      // 注意:createImageBitmap是異步的  
      const imgBitmap = createImageBitmap(blob);  
  
      // ImageBitmap對象創(chuàng)建成功后,會執(zhí)行以下操作  
      imgBitmap.then(function (bitmap) {  
        // 創(chuàng)建一個與位圖尺寸相同的離屏Canvas  
        const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);  
  
        // 獲取這個離屏Canvas的2D渲染上下文  
        const ctx = canvas.getContext('2d');  
  
        // 在Canvas上繪制之前創(chuàng)建的位圖  
        ctx.drawImage(bitmap, 0, 0);  
  
        // 從Canvas上獲取整個圖像的圖像數(shù)據(jù)  
        const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);  
  
        // 獲取圖像數(shù)據(jù)的像素數(shù)組  
        const data = imageData.data;  
  
        // 遍歷每個像素,將彩色圖像轉(zhuǎn)換為灰度圖像  
        // 灰度是通過計算RGB三個通道的平均值,并將其設(shè)置為每個通道的值來得到的  
        for (let i = 0; i < data.length; i += 4) {  
          const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;  
          data[i] = avg;     // R  
          data[i + 1] = avg; // G  
          data[i + 2] = avg; // B  
        }  
  
        // 將處理后的灰度圖像數(shù)據(jù)重新放回Canvas  
        ctx.putImageData(imageData, 0, 0);  
  
        // 將Canvas內(nèi)容轉(zhuǎn)換為Blob對象  
        canvas.convertToBlob().then(blob => {  
          // 創(chuàng)建一個表示該Blob對象的URL  
          const newUrl = URL.createObjectURL(blob);  
          // 將處理后的灰度圖像的URL發(fā)送回主線程  
          _self.postMessage(newUrl);  
        });  
  
      }).catch(e => {  
        // 如果在處理ImageBitmap或Canvas時出現(xiàn)錯誤,拋出一個新的錯誤  
        // 這里可以添加更詳細(xì)的錯誤處理邏輯  
        throw new Error();  
      });  
  
    } catch (e) {  
      // 如果在嘗試獲取或處理圖像時發(fā)生任何錯誤(如網(wǎng)絡(luò)錯誤、fetch失敗等)  
      // 則將原始的圖像URL發(fā)送回主線程,表示處理失敗  
      _self.postMessage(imageUrl);  
    }  
  };  
};  
  
// 將workerCode函數(shù)轉(zhuǎn)換為字符串,并截取大括號內(nèi)的內(nèi)容作為Web Worker的代碼  
let code = workerCode.toString();  
code = code.substring(code.indexOf('{') + 1, code.lastIndexOf('}'));  
  
// 創(chuàng)建一個包含處理過的代碼的Blob對象  
const blob = new Blob([code], { type: 'application/javascript' });  
// 為這個Blob對象創(chuàng)建一個URL,這個URL可以被用作Web Worker的腳本源  
const workerScriptURL = URL.createObjectURL(blob);  
  
// 導(dǎo)出這個URL,以便其他模塊可以使用它來創(chuàng)建一個新的Web Worker  
export default workerScriptURL;

這樣組件就封裝完成了,在你需要的地方使用下面的代碼來調(diào)用上面的組件

import ImageProcessor from "@/component/ImageProcessor";
<ImageProcessor originSrc = {CompressImageUrl} />

你可以將上述代碼的這部分抽取成一個函數(shù),放到公用工具庫中:

// 遍歷每個像素,將彩色圖像轉(zhuǎn)換為灰度圖像  
// 灰度是通過計算RGB三個通道的平均值,并將其設(shè)置為每個通道的值來得到的  
for (let i = 0; i < data.length; i += 4) {  
  const avg = (data[i] + data[i + 1] + data[i + 2]) / 3;  
  data[i] = avg;     // R  
  data[i + 1] = avg; // G  
  data[i + 2] = avg; // B  
}  

這樣一來,通過替換像素算法就可以實現(xiàn)更加有趣且復(fù)雜的圖像處理了。

最后總結(jié)一下上面代碼中值得注意的細(xì)節(jié):

  • React Hooks的使用useState, useEffect, useRef這三個React Hooks在代碼中都被使用了。useState用于存儲處理后的圖片URL;useEffect用于在組件掛載、更新時執(zhí)行某些操作(如啟動和終止Web Worker);useRef用于存儲Web Worker的實例,并確保其在整個組件生命周期內(nèi)保持不變。
  • Web Worker的使用:為了提高性能,代碼使用了Web Worker來在后臺處理圖像轉(zhuǎn)換任務(wù),從而避免阻塞主線程。Web Worker通過postMessageonmessage進(jìn)行通信。
  • Blob和URL.createObjectURL:在處理圖像后,Web Worker使用BlobURL.createObjectURL創(chuàng)建了一個新的URL,這個URL指向包含處理后圖像數(shù)據(jù)的Blob對象。這樣可以在不將圖像數(shù)據(jù)實際寫入磁盤的情況下,將其作為一個可訪問的資源。
  • createImageBitmap和OffscreenCanvas:為了提高圖像處理性能,代碼中使用了createImageBitmap來高效地將Blob轉(zhuǎn)換為位圖,并使用OffscreenCanvas進(jìn)行離屏渲染。這兩個API都允許在不影響頁面渲染的情況下進(jìn)行高性能的圖像處理。
  • 灰度圖像處理:在Web Worker內(nèi)部,代碼遍歷了圖像的每個像素,并將其轉(zhuǎn)換為灰度。這是通過計算RGB通道的平均值,并將這個平均值設(shè)置為新的RGB值來實現(xiàn)的。
  • 動態(tài)創(chuàng)建Web Worker腳本worker.js文件最后將自身代碼轉(zhuǎn)換為字符串,并通過Blob和URL.createObjectURL創(chuàng)建了一個URL,這個URL被用作Web Worker的腳本源。這是一種動態(tài)創(chuàng)建和執(zhí)行JavaScript代碼的技術(shù),允許在不依賴外部文件的情況下運行Web Worker。
  • 錯誤處理和異常捕獲:在Web Worker內(nèi)部和外部都有錯誤處理和異常捕獲的邏輯。例如,在嘗試獲取或處理圖像時發(fā)生錯誤,會將原始的圖像URL發(fā)送回主線程表示處理失敗。
  • 使用nullish coalescing操作符:在JSX中,width ?? '100%'height ?? '100%'使用了nullish coalescing操作符(??),這是ES2020引入的新特性。它允許在左側(cè)操作數(shù)為nullundefined時返回右側(cè)的值,否則返回左側(cè)的值。這提供了一種簡潔的方式來為變量提供默認(rèn)值。
  • 圖片加載完成后的處理:在圖片加載完成后,會終止當(dāng)前的Web Worker。這有助于釋放資源并避免不必要的后臺處理。
  • 代碼組織和模塊導(dǎo)出ImageProcessor組件和workerScriptURL都被導(dǎo)出,以便在其他模塊中使用。這體現(xiàn)了良好的模塊化和代碼復(fù)用實踐。

以上就是React處理復(fù)雜圖片樣式的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于React處理圖片樣式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React狀態(tài)管理Redux的使用介紹詳解

    React狀態(tài)管理Redux的使用介紹詳解

    redux是redux官方react綁定庫,能夠使react組件從redux store中讀取數(shù)據(jù),并且向store分發(fā)actions以此來更新數(shù)據(jù),這篇文章主要介紹了react-redux的設(shè)置,需要的朋友可以參考下
    2022-09-09
  • 在react-router4中進(jìn)行代碼拆分的方法(基于webpack)

    在react-router4中進(jìn)行代碼拆分的方法(基于webpack)

    這篇文章主要介紹了在react-router4中進(jìn)行代碼拆分的方法(基于webpack),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • React中事件綁定的5種實現(xiàn)方式和優(yōu)劣對比全攻略

    React中事件綁定的5種實現(xiàn)方式和優(yōu)劣對比全攻略

    在React中,事件綁定不僅僅是把函數(shù)和元素連接起來那么簡單,它關(guān)系到很多方面,下面我們就來一起來看看React事件綁定的5種主要方式,以及它們各自的優(yōu)缺點吧
    2026-01-01
  • react native實現(xiàn)監(jiān)控手勢上下拉動效果

    react native實現(xiàn)監(jiān)控手勢上下拉動效果

    這篇文章主要為大家詳細(xì)介紹了react native實現(xiàn)監(jiān)控手勢上下拉動效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • react實現(xiàn)同頁面三級跳轉(zhuǎn)路由布局

    react實現(xiàn)同頁面三級跳轉(zhuǎn)路由布局

    這篇文章主要為大家詳細(xì)介紹了react實現(xiàn)同頁面三級跳轉(zhuǎn)路由布局,一個路由小案例,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • React代碼分割的實現(xiàn)方法介紹

    React代碼分割的實現(xiàn)方法介紹

    雖然一直有做react相關(guān)的優(yōu)化,按需加載、dll 分離、服務(wù)端渲染,但是從來沒有從路由代碼分割這一塊入手過,所以下面這篇文章主要給大家介紹了關(guān)于React中代碼分割的方式,需要的朋友可以參考下
    2022-12-12
  • React父子組件回調(diào)傳參的避坑指南

    React父子組件回調(diào)傳參的避坑指南

    在React開發(fā)中,父子組件間的通信是高頻需求,其中通過回調(diào)函數(shù)傳遞參數(shù)更是核心場景,但很多開發(fā)者在實際編碼中會遇到諸如參數(shù)傳不到、函數(shù)提前執(zhí)行、組件無限渲染等問題,文結(jié)合實際開發(fā)案例,拆解回調(diào)傳參的核心邏輯,剖析常見錯誤,需要的朋友可以參考下
    2025-12-12
  • jsoneditor二次封裝實時預(yù)覽json編輯器組件react版

    jsoneditor二次封裝實時預(yù)覽json編輯器組件react版

    這篇文章主要為大家介紹了jsoneditor二次封裝實時預(yù)覽json編輯器組件react版示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • 深入理解React中es6創(chuàng)建組件this的方法

    深入理解React中es6創(chuàng)建組件this的方法

    this的本質(zhì)可以這樣說,this跟作用域無關(guān)的,只跟執(zhí)行上下文有關(guān)。接下來通過本文給大家介紹React中es6創(chuàng)建組件this的方法,非常不錯,感興趣的朋友一起看看吧
    2016-08-08
  • react-redux的connect示例詳解

    react-redux的connect示例詳解

    connect()是react-redux中的核心方法之一,它將react組件預(yù)redux中的Store真正連接在一起,這篇文章主要介紹了react-redux的connect詳解,需要的朋友可以參考下
    2023-01-01

最新評論

新泰市| 南城县| 南宁市| 湾仔区| 故城县| 察哈| 河间市| 彭阳县| 彩票| 新密市| 凤台县| 长子县| 饶平县| 漾濞| 海门市| 仁化县| 邯郸县| 朝阳市| 泗水县| 江达县| 乌拉特后旗| 罗田县| 昭通市| 香河县| 科尔| 筠连县| 凌云县| 东至县| 朝阳市| 霍城县| 和政县| 延边| 贡嘎县| 马尔康县| 哈巴河县| 忻州市| 遵义县| 华池县| 开封县| 西丰县| 新龙县|