久久r热视频,国产午夜精品一区二区三区视频,亚洲精品自拍偷拍,欧美日韩精品二区

您的位置:首頁技術(shù)文章
文章詳情頁

Java 3D的動(dòng)畫展示(Part1-使用JMF)

瀏覽:134日期:2024-06-12 13:15:54
內(nèi)容: Java 3D的動(dòng)畫展示(Part1-使用JMF)翻譯:Andrew Davison, Killer Game Programming in Java的作者06/01/2005 翻譯 Caesh版權(quán)聲明:可以任意轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明英文原文地址:http://www.onjava.com/pub/a/onjava/2005/06/01/kgpjava.html中文地址:http://www.matrix.org.cn/resource/article/43/43675_Java_3D.html關(guān)鍵詞: Java 3D JMF在Java 3D場(chǎng)景中插入動(dòng)畫片段使3D內(nèi)容更加有趣充實(shí).一段動(dòng)畫可以在更令人信服的背景下展示,例如飄動(dòng)的云,繁忙的城市街道,或者是從窗向外看的效果.動(dòng)畫可以在屏幕效果和游戲效果之間任意轉(zhuǎn)換.這篇文章被分為兩個(gè)部分,描寫我怎樣實(shí)現(xiàn)一個(gè)Java 3D動(dòng)畫屏幕效果.在這個(gè)部分,我將說明我怎樣利用JMF(Java Media Framework),特別是在JMF Performance Pack for Windows v.2.1.1e情況下.我的另外兩個(gè)工具是J2SE 5.0和Java 3D 1.3.2.我將討論另外的使用Quicktime for Java的動(dòng)畫屏幕版本.圖1是應(yīng)用JMF Movie3D在不同時(shí)間截取的兩幅截屏,右邊截屏是從屏幕后看的效果. 圖1. Movie3D應(yīng)用截屏此應(yīng)用程序中重點(diǎn):。JMF和Java 3D的集成.屏幕以任意尺寸成倍增加在一個(gè)應(yīng)用程序.由于屏幕是Java3D的Shape3D類的一個(gè)子類,因此它可以很容易的統(tǒng)一到各種Java 3D場(chǎng)景中.。程序執(zhí)行使用Model-View-Controller設(shè)計(jì)模式.屏幕是一個(gè)視頻元素,由JMFMovieScreen類描述.動(dòng)畫是一個(gè)由JMFSnapper類控制的模型部分.一個(gè)Java 3D Behavior類,TimeBehavior,控制動(dòng)畫定時(shí)定期更新.所有JMF編碼都存放在JMFSnapper類,可以很方便的測(cè)試各種變化.這篇文章的第二部分JMFSnapper由QuickTime for Java版本中的QTSnapper取代.。Java 3D 的使用將會(huì)使動(dòng)畫的播放速度毫無困難的上升到25幀/秒.。使用JMF出現(xiàn)問題的討論.問題是我首選解決方案將不會(huì)工作-JMF有可能變?yōu)橐粋€(gè)巨大的API,但在其內(nèi)部仍有一些程序沒有及時(shí)運(yùn)行.1. 我坐在山上事實(shí)上,我正坐在一個(gè)冰冷的辦公室.我真正的意思是說這篇文章建立在大量Java 3D和JMF背景知識(shí)之上.我將不會(huì)細(xì)致地解釋Java 3D的基礎(chǔ)知識(shí),因?yàn)樗鼈兌伎梢栽贠'Reilly文章Killer Game Programming in Java(以下簡(jiǎn)稱KGPJ)中找到.例如,圖1場(chǎng)景效果圖是其第15章中的輕微改良Checkers3D的版本實(shí)例.我再生了這些編碼以生成底版,藍(lán)天和燈光.假如你不想買這本書,沒關(guān)系,所有篇章的初稿和所有編碼都可以在此書的站點(diǎn)查閱.在此文章中,我將會(huì)解釋我用來從動(dòng)畫中抽取幀的JMF技術(shù).我將不會(huì)討論流媒體或者編碼轉(zhuǎn)換.2. 應(yīng)用簡(jiǎn)述動(dòng)畫由JMFSnapper類加載播放,并且不斷的循環(huán)播放直到被停止.JMFMovieScreen生成動(dòng)畫屏幕,并在底版上控制Java 3D四邊形.圖2顯示這些類的應(yīng)用(該場(chǎng)景圖說明場(chǎng)景中Java 3D節(jié)點(diǎn)怎樣連接在一起) 圖2:Movie3D場(chǎng)景圖圖2種的很多細(xì)節(jié)可以被忽略,此圖KGPJ15章中的得Checkers3D實(shí)例有很多相似之處. 只有特殊動(dòng)畫的節(jié)點(diǎn)是新的.由于節(jié)點(diǎn)關(guān)系,JMFMovieScreen和TimeBehavior對(duì)象以三角形表示.JMFSnapper對(duì)象不屬于這張圖,但由JMFMovieScreen調(diào)用.每40毫秒,TimeBehavior對(duì)象調(diào)用JMFMovieScreen類中的nextFrame()方法.接下來調(diào)用JMFSnapper中的getFrame()方法獲取動(dòng)畫中當(dāng)前播放的幀,由JMFMovieScreen控制成像.TimeBehavior是Java 3D的Behavior類的子類,它是Java 3D應(yīng)用的計(jì)時(shí)器.它與KGPJ18章中的3D sprites實(shí)例中的TimeBehavior類十分相似.觀察應(yīng)用過程的另一種方式就是察看它的UML類圖表,圖3給出。類中的公共方法被顯示.圖3:Movie3D類圖表Movie3D的子類JFrame,WrapMovie3D是JPanel的一個(gè)子類.圖2展示了WrapMovie3D如何構(gòu)建場(chǎng)景圖,和將其譯成應(yīng)用的JPanel.他使用CheckerFloor 和ColouredTiles類構(gòu)建底版.JMFMovieScreen創(chuàng)建動(dòng)畫屏幕,將其加入場(chǎng)景中,通過創(chuàng)建一個(gè)JMFSnapper對(duì)象開始動(dòng)畫.TimeBehavior每40毫秒調(diào)用JMFMovieScreen中的nextFrame()方法. nextFrame()調(diào)用JMFSnapper中的getFrame()得到當(dāng)前幀. 這個(gè)例子中的所有編碼,此文章的早期版本可以在KGPJ網(wǎng)點(diǎn)查詢.3. 準(zhǔn)備動(dòng)畫動(dòng)畫,它的屏幕和更新屏幕的TimeBehavior對(duì)象,都是由WrapMovie3D中的addMovieScreen()方法創(chuàng)立.// globalsprivate BranchGroup sceneBG;private JMFMovieScreen ms; // the movie screenprivate TimeBehavior timer; // to update screenprivate void addMovieScreen(String fnm){ // put the movie in fnm onto a movie screen ms = new JMFMovieScreen( new Point3f(1.5f, 0, -1), 2.0f, fnm); sceneBG.addChild(ms); // set up the timer for animating the movie timer = new TimeBehavior(40, ms); // update movie every 40ms (== 25 frames/sec) timer.setSchedulingBounds(bounds); sceneBG.addChild(timer);} 兩個(gè)Java 3D addChild()方法調(diào)用JMFMovieScreen和TimeBehavior節(jié)點(diǎn)間的連接.setSchedulingBounds()激活TimeBehavior節(jié)點(diǎn).4. 創(chuàng)建動(dòng)畫屏幕JMFMovieScreen是Java 3D的Shape3D類的一個(gè)子類.所以必須仔細(xì)說明它的外形的幾何形狀和外觀.幾何形狀是指動(dòng)畫圖像的四個(gè)邊尺寸上成比例,它的最大尺寸(高 寬)必須向構(gòu)造器仔細(xì)說明.這個(gè)四方形是垂直的,朝向Z軸正方向,可以在底版的任何位置被定位.四方形外觀是雙面,允許從前或后觀看動(dòng)畫.結(jié)構(gòu)是用雙線性插值,可以降低動(dòng)畫圖像的像素化.大多數(shù)的功能是從KGPJ24章中的FPS(first-person shooter)實(shí)例中的ImageCsSeries類拷貝而來. ImageCsSeries在一個(gè)區(qū)域中顯示一系列的GIF圖片. 為了簡(jiǎn)短起見,我僅描述了JMFMovieScreen與ImageCsSeries的不同特征.高效顯示圖像動(dòng)畫中的一個(gè)幀被轉(zhuǎn)換結(jié)構(gòu)擴(kuò)大四倍;分為兩個(gè)步驟:第一步 提供的BufferedImage傳給Java 3D的ImageComponent2D對(duì)象,然后傳給Java 3D Texture2D.區(qū)域的圖像更新非常快:每秒更新25幀,要求結(jié)構(gòu)更新25次.因此結(jié)構(gòu)有效率的更新非常的重要.這種高效率在利用BufferedImage和ImageComponent2D對(duì)象進(jìn)行格式化的情況下是可能的.JMFMovieScreen使用的ImageComponent2D對(duì)象以以下方式聲明:ImageComponent2D ic = new ImageComponent2D( ImageComponent2D.FORMAT_RGB, FORMAT_SIZE, FORMAT_SIZE, true, true);構(gòu)造器剩余兩個(gè)需要說明的討論點(diǎn)是它使用'by reference'和'Y-up'模式.這些模式降低了存儲(chǔ)結(jié)構(gòu)圖像的內(nèi)存大小,因?yàn)镴ava 3D避免將圖像從應(yīng)用空間拷貝到圖形內(nèi)存. 在Windows OS環(huán)境下,使用OpenGL作為Java 3D優(yōu)先圖像引擎,ImageComponent2D格式應(yīng)是ImageComponent2D.FORMAT_RGB,BufferedImage格式應(yīng)是BufferedImage.TYPE_3BYTE_BGR.BufferedImage格式在JMFSnapper中確定.此項(xiàng)技術(shù)的更多細(xì)節(jié)可以在j3d.org中查詢.將紋理加進(jìn)區(qū)域通常在一個(gè)區(qū)域中確定一幅圖像的方法是將圖像的坐下角連接到區(qū)域的左下角,然后逆時(shí)針連接剩余的幾個(gè)角.圖4說明這種方法. 圖4.圖像與區(qū)域之間的標(biāo)準(zhǔn)連接圖像坐標(biāo)區(qū)間在X Y軸的0 1之間,Y軸正方向.例如,圖像左下點(diǎn)坐標(biāo)為(0,0),右上點(diǎn)為(1,1).當(dāng)'Y-up'模式使用,圖像坐標(biāo)Y軸翻轉(zhuǎn),負(fù)方向.意味著(0,0)代表圖像左上點(diǎn),(1,1)指向右下.當(dāng)'Y-up'模式建立,圖像坐標(biāo)必須分配給區(qū)域中不同點(diǎn)以便獲得圖像的相同定位.圖5顯示了最新配置. 圖5.'Y-up'模式使用時(shí),圖像與區(qū)域之間的連接連接區(qū)域點(diǎn)與圖像定位的JMFMovieScreen編碼是TexCoord2f q = new TexCoord2f();q.set(0.0f, 0.0f); plane.setTextureCoordinate(0, 3, q); // (0,0) tex coord top left quad point (p3)q.set(1.0f, 0.0f); plane.setTextureCoordinate(0, 2, q); // (1,0) top right (p2)q.set(1.0f, 1.0f); plane.setTextureCoordinate(0, 1, q); // (1,1) bottom right (p1)q.set(0.0f, 1.0f); plane.setTextureCoordinate(0, 0, q); // (0,1) bottom left (p0)PLANE對(duì)象指代區(qū)域.更新圖像以上所講,TimeBehavior是被設(shè)置用來被40毫秒調(diào)用JMFMovieScreen的nextFrame()方法.nextFrame()調(diào)用JMFSnapper對(duì)象中的getFrame()方法獲得被看作BufferedImage對(duì)象的當(dāng)前動(dòng)畫幀.指派給一個(gè)mageComponent2D對(duì)象,然后傳給區(qū)域圖像.nextFrame()是:// globalsprivate Texture2D texture; // used by the quadprivate ImageComponent2D ic;private JMFSnapper snapper; // to take snaps of the movieprivate boolean isStopped = false; // is the movie stopped?public void nextFrame(){ if (isStopped) // movie has been stopped return; BufferedImage im = snapper.getFrame();// get current frame if (im != null) { ic.set(im); //assign frame to ImageComponent2D texture.setImage(0,ic); // make it the shape's texture } else System.out.println('Null BufferedImage');}snapper,JMFSnapper對(duì)象,由JMFMovieScreen的構(gòu)造器創(chuàng)建:// load and play the moviesnapper = new JMFSnapper(movieFnm);JMFSnapper的簡(jiǎn)單接口掩蓋了播放動(dòng)畫和從動(dòng)畫中抽取幀的JMF編碼的復(fù)雜.著這個(gè)系列的第二部分,JMFSnapper由使用QuickTime for Java的版本取代,對(duì)JMFMovieScreen只需要作出微小改動(dòng).5. 管理動(dòng)畫JMF提供了一種訪問動(dòng)畫幀的高水平方法.以下的編碼片斷闡明了主要元素.我將省去錯(cuò)誤檢驗(yàn)和異常處理.// create a movie player, in a 'realized' stateURL url = new URL('file:' + movieFnm);Player p = Manager.createRealizedPlayer(url);// create a frame positionerFramePositioningControl fpc = (FramePositioningControl) p.getControl('javax.media.control. FramePositioningControl');// create a frame grabberFrameGrabbingControl fg = (FrameGrabbingControl) p.getControl('javax.media.control. FrameGrabbingControl');// request that the player changes to a 'prefetched' statep.prefetch();// wait until the player is in that state...// move to a particular frame, e.g. frame 100fpc.seek(100); // take a snap of the current frameBuffer buf = fg.grabFrame(); // get its video format detailsVideoFormat vf = (VideoFormat) buf.getFormat();// initialize BufferToImage with video formatBufferToImage bufferToImage = new BufferToImage(vf);// convert the buffer to an imageImage im = bufferToImage.createImage(buf);// specify the format of desired BufferedImageBufferedImage formatImg = new BufferedImage( FORMAT_SIZE, FORMAT_SIZE, BufferedImage.TYPE_3BYTE_BGR);// convert the image to a BufferedImageGraphics g = formatImg.getGraphics();g.drawImage(im, 0, 0, FORMAT_SIZE, FORMAT_SIZE, null);g.dispose();一個(gè)媒體播放器從制作到完成需要六個(gè)步驟.播放器在構(gòu)思過程中要清楚怎樣運(yùn)行數(shù)據(jù),可以在要求時(shí)提供視覺上的組成和控制器.我要求兩個(gè)控制器:FramePositioningControl和FrameGrabbingControl. FramePositioningControl提供了seek()和skip()方法,可以在動(dòng)畫中查檢特殊幀.FrameGrabbingControl提供grabFrame()方法,可以在動(dòng)畫的視頻軌跡中抽取當(dāng)前幀.為了使這些控制器工作,播放器必須由構(gòu)思過程進(jìn)入構(gòu)建過程.播放器開始準(zhǔn)備播放媒體,媒體數(shù)據(jù)被加載.prefetch()的調(diào)用是異步的,意味著編碼必須等待直到轉(zhuǎn)換過程結(jié)束.標(biāo)準(zhǔn)JMF譯碼解決方案使用waitForState()方法,此方法將使執(zhí)行過程暫停直到一個(gè)狀態(tài)轉(zhuǎn)換事件將其喚醒.如果想尋找一個(gè)幀,可以使用seek()方法在軌跡中將這個(gè)幀定位,然后利用grabFrame()方法提取.提取的Buffer對(duì)象轉(zhuǎn)變?yōu)镴MFMovieScreen要求的 BufferedImage對(duì)象必須經(jīng)過幾個(gè)轉(zhuǎn)變過程.注意:BufferedImage對(duì)象是TYPE_3BYTE_BGR格式.Sun公司的JMF website有很多很有用的小例子,其中之一,Seek.java展示了如何使用FramePositioningControl方法做成動(dòng)畫.三步審查不幸的是,編碼大體上是錯(cuò)誤的,至少在JMF Performance Pack for Windows v.2.1.1e.我審查了幾個(gè)編碼重寫以獲得可工作的JMFSnapper版本.1. 兩個(gè)控制器,F(xiàn)ramePositioningControl和FrameGrabbingControl,在JMF下的缺省播放器模塊中是很難獲得的.'本地模塊'播放器被要求:Manager.setHint(Manager.PLUGIN_PLAYER, new Boolean(true));這個(gè)播放器組成龐大,對(duì)Swing GUIs例如JFrame和JPanel會(huì)產(chǎn)生弱化的影響.然而,我不需要展示這個(gè)播放器.使用本地模塊播放器會(huì)產(chǎn)生一系列嚴(yán)重的后果,媒體加載時(shí)間過長(zhǎng),無序播放.2.在一番沉思后,我確定了加速播放器的最佳方法是減少其工作量.我將音頻從MPEG文件剝離,確保文件以簡(jiǎn)單的MPEG-1格式儲(chǔ)存.一些視頻編輯工具可以完成這些工作.我使用的是兩個(gè)免費(fèi)的工具:MPEG Properties和FlasKMPEG.被剝離的動(dòng)畫播放很順暢,幀率是一個(gè)常數(shù),沒有幀遺漏.不過,F(xiàn)ramePositioningControl類是不可靠的.在我的WinXP機(jī)器,seek()方法幾乎總是失敗,skip()方法五次也只能成功一次.3.我下定決心舍棄FramePositioningControl.我的幀抓取運(yùn)算法則依賴每隔一段時(shí)間調(diào)用FrameGrabbingControl的grabFrame()方法當(dāng)播放器播放動(dòng)畫.我已有可以很可靠的從只有視頻的MPEG-1文件中抓取幀的編碼.它也可以從視頻音頻齊全的文件中還算不錯(cuò)的抓取幀,但是播放器啟動(dòng)會(huì)很慢.而且,無序播放會(huì)引起幀的不規(guī)律抓取.我在JMFSnapper前段加寫了“等待編碼以處理視頻-音頻文件.JMFSnapper對(duì)象等待播放器啟動(dòng)和第一個(gè)動(dòng)畫幀變的可用.等待第一幀JMFSnapper構(gòu)造器調(diào)用waitForBufferToImage()方法以便重復(fù)的調(diào)用hasBufferToImage()直到它檢測(cè)到第一個(gè)視頻幀.hasBufferToImage()調(diào)用FrameGrabbingControl的grabFrame(),檢測(cè)返回的Buffer對(duì)象是否含有視頻信息數(shù)據(jù).它使用這些數(shù)據(jù)初始化一個(gè)BufferToImage對(duì)象,此對(duì)象被用來將每一個(gè)抓取幀轉(zhuǎn)化為圖像.// globalsprivate FrameGrabbingControl fg; // frame grabberprivate BufferToImage bufferToImage = null;private int width, height; // frame dimensionsprivate boolean hasBufferToImage(){ Buffer buf = fg.grabFrame(); // take a snap if (buf == null) { System.out.println('No grabbed frame'); return false; } // there is a buffer, but check if it's empty VideoFormat vf = (VideoFormat) buf.getFormat(); if (vf == null) { System.out.println('No video format'); return false; } System.out.println('Video format: ' + vf); // extract the image's dimensions width = vf.getSize().width; height = vf.getSize().height; // initialize bufferToImage with video format bufferToImage = new BufferToImage(vf); return true;}這個(gè)編碼方法的一個(gè)微小缺點(diǎn)是第一個(gè)視頻幀(引起hasBufferToImage()返回true)在BufferToImage對(duì)象初始化后被丟棄.作為BufferedImage to JMFMovieScreen這個(gè)幀不能被使用.抓圖JMFSnapper中的最重要的公共方法是getFrame(),此方法被周期性的調(diào)用以獲得播放動(dòng)畫中的當(dāng)前幀.// globalprivate BufferedImage formatImg; // frame imagesynchronized public BufferedImage getFrame(){ // grab the current frame as a buffer object Buffer buf = fg.grabFrame(); if (buf == null) { System.out.println('No grabbed buffer'); return null; } // convert buffer to image Image im = bufferToImage.createImage(buf); if (im == null) { System.out.println('No grabbed image'); return null; } // convert the image to a BufferedImage Graphics g = formatImg.getGraphics(); g.drawImage(im, 0, 0, FORMAT_SIZE, FORMAT_SIZE, null); // Overlay current time on top of the image g.setColor(Color.RED); g.setFont(new Font('Helvetica',Font.BOLD,12)); g.drawString(timeNow(), 5, 14); g.dispose(); return formatImg;} // end of getFrame() getFrame()和closeMovie()方法在JMFSnapper中是同步的.closeMovie()中止播放器,在任何時(shí)間都可能被調(diào)用.同步關(guān)鍵字確保當(dāng)幀從動(dòng)畫中被抽取時(shí)播放器不會(huì)被關(guān)閉. formatImg BufferedImage對(duì)象在JMFSnapper構(gòu)造器中初始化:formatImg = new BufferedImage( FORMAT_SIZE, FORMAT_SIZE, BufferedImage.TYPE_3BYTE_BGR);6. 另一種抓圖方案 Sun公司的JMF實(shí)例網(wǎng)點(diǎn)提供了另外兩種抽取幀方法.VideoRendererDemoJMFJ3D實(shí)例由Java 3D和JMF應(yīng)用程序組成,它展示了怎樣將一個(gè)視頻環(huán)繞一個(gè)主體.Java 3D與我討論的一些東西-使用 BufferedImage.TYPE_3BYTE_BGR格式的BufferedImage傳遞給ImageComponent2D對(duì)象,然后變?yōu)橹鎴D像-在本質(zhì)上是相同的.這個(gè)圖像也使用BufferedImage.TYPE_4BYTE_ABGR格式,此格式是Solaris要求的以便符合提及的圖像格式.這個(gè)程序的JMF與我們的相當(dāng)不同.一個(gè)JMF的VideoRenderer應(yīng)用程序接口是附加在TrackControl對(duì)象,此對(duì)象是控制動(dòng)畫的視頻軌跡.一旦TrackControl對(duì)象被喚醒,VideoRenderer的process()方法被自動(dòng)調(diào)用以便適用視頻中的每一個(gè)幀.process()的輸入是Buffer對(duì)象.勝于我曾描述的Buffer-to-BufferedImage轉(zhuǎn)換步驟,DemoJMFJ3D以低水準(zhǔn)構(gòu)建BufferedImage,BufferedImage的像素化圖像和Buffer原始數(shù)據(jù)時(shí)間的比特?cái)?shù)組拷貝.3D聊天室實(shí)例中的DemoJMFJ3D編碼盡在Java Media APIs: Cross-Platform Imaging, Media and Visualization,A. Terrazas, J. Ostuni和M. Barlow所著.這本書是對(duì)于JMF是本很好的入門書籍,其中也有很多關(guān)于Java 3D的有趣篇章.Processor Codec插件FrameAccess實(shí)例使用很多更先進(jìn)的JMF元素,以Processor codec插件為中心.Processor類是Player的一個(gè)延伸版本,它對(duì)于媒體數(shù)據(jù)處理有更強(qiáng)的能力.一個(gè)多媒體數(shù)字信號(hào)編解碼器插件能夠從一段軌跡中讀取幀,以任意方式處理它們,然后將他們寫回軌跡.Codec的process()方法中,提供其一個(gè)含有輸入幀的Buffer對(duì)象,空Buffer對(duì)象輸出.FrameAccess附加一個(gè)Codec插件以訪問動(dòng)畫的視頻軌跡,使用輸入幀Buffer對(duì)象傳遞給process()方法以產(chǎn)生一些關(guān)于視頻的基本統(tǒng)計(jì)表.這個(gè)實(shí)例易于改進(jìn)以便將Buffer對(duì)象轉(zhuǎn)化為BufferedImage,任意使用我的方法或者DemoJMFJ3D的比特?cái)?shù)組技術(shù).不幸的是,Processor類不能用來支持插件;結(jié)果,插件在JMF 1.0或2.0-based版本下不能工作.在使用Sun公司的JMF實(shí)例前尋找jmf-interest mailing list是一個(gè)不錯(cuò)的注意,因?yàn)榇蠖鄶?shù)的程序在各種版本的JMF下都存在問題. Java, java, J2SE, j2se, J2EE, j2ee, J2ME, j2me, ejb, ejb3, JBOSS, jboss, spring, hibernate, jdo, struts, webwork, ajax, AJAX, mysql, MySQL, Oracle, Weblogic, Websphere, scjp, scjd
標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 马鞍山市| 田林县| 杭州市| 通渭县| 大新县| 伊川县| 健康| 邮箱| 刚察县| 泸西县| 灵璧县| 陇西县| 汾西县| 南昌市| 嘉兴市| 澄江县| 东丽区| 惠来县| 新和县| 华容县| 岑溪市| 茶陵县| 双鸭山市| 承德县| 郓城县| 治多县| 贡嘎县| 阿图什市| 虹口区| 五峰| 陇川县| 新安县| 阿鲁科尔沁旗| 南漳县| 开平市| 开封县| 通州市| 嵊州市| 亳州市| 滁州市| 二连浩特市|