ArcEngine地圖窗口指定區域導出指定DPI多格式---delphi/C#實現
阿新 • • 發佈:2018-05-03
common RM apu sage rto logical onf 出圖 mfc
delphi/C#實現,其他語言稍微改下就行了。AE的編碼各個語言都差不多,這裏也沒用到某一語言的特性。 函數特點: 1.可以精確導出指定範圍的圖形要素 2.支持多格式.TIF, .EMF,.GIF,.PDF,.PNG,.SVG,.AI,.EPS,.jpg等 3.Tif格式導出時支持坐標信息導出,支持壓縮格式選擇 delphi 版: 復制代碼 {海龍 created 功能說明:指定地圖窗口指定區域裁圖 參數說明: 指定地圖窗口pMap 指定範圍裁圖pExtent,如某一圖形的envolope或map.extent之類的 輸出圖片文件名稱strPicFile,根據後綴名判斷裁出圖片類型 輸出圖片dpi iOutResolution ,默認300 裁圖時地圖窗口需設置的比例尺 sMapBLC ,可以為空 bGeoTiff 文件類型為tif時有效,為true時保存坐標信息 pTifCompressionType 文件類型為tif時有效,tif的壓縮類型,默認無損} function ClipMap2Pic(pMap: IMap;pExtent: IEnvelope; strPicFile: String; iOutResolution: Integer = 300; sMapBLC: String = ‘‘; bGeoTiff : Boolean = False; pTifCompressionType: esriTIFFCompression = esriTIFFCompressionNone):Boolean; var pAV: IActiveView; pEnvNew: IEnvelope; ptagTmp: tagRECT; pExport: IExport; ihdc, iPrevOutputImageQuality: Integer; dRes: Double; dWidth, dHeight, dMapBLC: Double; tmpDC: HDC; iScreenResolution: Integer; deviceRECT: tagRECT; pSD: IScreenDisplay; pDT: IDisplayTransformation; sWJLX:string; //地圖距離轉屏幕像素數,不同縮放比例尺下同樣距離對應像素數不同的,有特殊需要時設置sMapBLC function ConvertMapUnitsToPixels(pAV: IActiveView;dMapUnits: Double):double; var pBounds: IEnvelope; pDeviceFrame: tagRECT; iDeviceRight, iDeviceLeft, iPixelExtent: integer; dRealWorldExtent, dSizeOfEachPixel: double;begin Result:= 600; pDT.Get_DeviceFrame(pDeviceFrame); iDeviceLeft:= pDeviceFrame.left; iDeviceRight:= pDeviceFrame.right; iPixelExtent:= iDeviceRight-iDeviceLeft; pDT.Get_VisibleBounds(pBounds); pBounds.Get_Width(dRealWorldExtent); dSizeOfEachPixel:= dRealWorldExtent / iPixelExtent; Result:= dMapUnits/dSizeOfEachPixel ; end; begin Result:= False; if pMap = nil then Exit; if strPicFile = ‘‘ then Exit; try if FileExists(strPicFile) then DeleteFile(PChar(strPicFile)); if (sMapBLC <> ‘‘) and TryStrToFloat(sMapBLC, dMapBLC) and (dMapBLC > 0) then pMap.Set_MapScale(StrToFloatEx(sMapBLC));//map的比例尺調整為出圖比例尺 pAV:= pMap as IActiveView; sWJLX := UpperCase(RightStr(strPicFile, 4)); if sWJLX = ‘.TIF‘ then //根據文件名後4位判斷輸出類型 pExport := CoExportTiff.Create as IExport else if sWJLX = ‘.EMF‘ then pExport := CoExportEMF.Create as IExport else if sWJLX = ‘.BMP‘ then pExport := CoExportBMP.Create as IExport else if sWJLX = ‘.GIF‘ then pExport := CoExportGIF.Create as IExport else if sWJLX = ‘.PDF‘ then pExport := CoExportPDF.Create as IExport else if sWJLX = ‘.PNG‘ then pExport := CoExportPNG.Create as IExport else if sWJLX = ‘.SVG‘ then pExport := CoExportEMF.Create as IExport else if RightStr(sWJLX, 3) = ‘.AI‘ then pExport := CoExportAI.Create as IExport else if sWJLX = ‘.EPS‘ then pExport := CoExportPS.Create as IExport else pExport := CoExportJPEG.Create as IExport; pAV.Get_ScreenDisplay(pSD); pSD.Get_DisplayTransformation(pDT); (pDT as IOutputRasterSettings).Get_ResampleRatio(iPrevOutputImageQuality); tmpDC:= GetDC(0); iScreenResolution:= GetDeviceCaps(tmpDC, 88); //獲取屏幕dpi ReleaseDC(0, tmpDC); // 根據傳入的pExtent確定裁圖的畫布大小(出圖比例尺下裁圖範圍的像素高和寬) pExtent.Get_Width(dWidth); pExtent.Get_Height(dHeight); ptagTmp.left := 0; //ptagTmp的right和bottom非常主要 ptagTmp.top := 0; ptagTmp.right := trunc(ConvertMapUnitsToPixels(pAV,dWidth) * iOutResolution / iScreenResolution); //把地圖距離轉為屏幕像素個數 ptagTmp.bottom := trunc(ConvertMapUnitsToPixels(pAV,dHeight) * iOutResolution / iScreenResolution); pEnvNew:= CoEnvelope.Create as IEnvelope; pEnvNew.PutCoords(ptagTmp.left,ptagTmp.top,ptagTmp.right,ptagTmp.bottom); //裁圖的畫布大小 pExport.Set_ExportFileName(strPicFile); pExport.Set_Resolution(iOutResolution); pExport.Set_PixelBounds(pEnvNew); if sWJLX = ‘.TIF‘ then begin if bGeoTiff then begin (pExport as IExportTIFF).Set_GeoTiff(True);//包含tif文件坐標信息,這2句是必須的 (pExport as IWorldFileSettings).Set_MapExtent(pExtent); end; (pExport as IExportTIFF).Set_CompressionType(pTifCompressionType); end; if sWJLX = ‘.PDF‘ then begin (pExport as IExportPDF).Set_Compressed(True); (pExport as IExportPDF).Set_EmbedFonts(True); (pExport as IExportPDF).Set_ImageCompression(esriExportImageCompressionNone); end; pExport.StartExporting(ihdc); pAV.Output(ihdc, iOutResolution, ptagTmp, pExtent, nil); pExport.FinishExporting; pExport.Cleanup; (pDT as IOutputRasterSettings).Set_ResampleRatio(iPrevOutputImageQuality); if FileExists(strPicFile) then Result:= True; except Result:= False; end; end; 復制代碼 C#版本: 復制代碼 /* GDI delegate to GetDeviceCaps function */ [DllImport("GDI32.dll")] public static extern int GetDeviceCaps(int hdc, int nIndex); /* User32 delegates to getDC and ReleaseDC */ [DllImport("User32.dll")] public static extern int GetDC(int hWnd); [DllImport("User32.dll")] public static extern int ReleaseDC(int hWnd, int hDC); [DllImport("user32.dll", SetLastError = true)] static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref int pvParam, uint fWinIni); /// <summary> /// 地圖距離轉屏幕像素數,不同縮放比例尺下同樣距離對應像素數不同的,有特殊需要時設置sMapBLC /// </summary> /// <param name="pAV">The p AV.</param> /// <param name="dMapUnits">地圖距離</param> /// <returns></returns> public static double ConvertMapUnitsToPixels(IActiveView pAV, double dMapUnits) { IDisplayTransformation pDT = pAV.ScreenDisplay.DisplayTransformation; tagRECT pDeviceFrame = pDT.get_DeviceFrame(); int iDeviceLeft = pDeviceFrame.left; int iDeviceRight = pDeviceFrame.right; int iPixelExtent = iDeviceRight-iDeviceLeft; double dRealWorldExtent = pAV.Extent.Width; double dSizeOfEachPixel = dRealWorldExtent / iPixelExtent; return dMapUnits / dSizeOfEachPixel; } /// <summary> /// 指定範圍裁剪圖片 /// </summary> /// <param name="pMap">裁圖地圖窗口</param> /// <param name="pExtent">指定裁圖範圍</param> /// <param name="strPicFile">輸出文件名稱</param> /// <param name="iOutResolution">輸出DPI</param> public static void ClipMap2Pic(IMap pMap, IEnvelope pExtent, string strPicFile, int iOutResolution, double blc, bool withWarning) { if (pMap == null) return; if (strPicFile == string.Empty) return; if (File.Exists(strPicFile)) { if ((!withWarning) || (withWarning && (GtMap.GxFrame.GxFrameLib.Common.AxMessageBox.ShowConfirmation("圖片已存在,是否覆蓋?") == System.Windows.Forms.DialogResult.Yes))) File.Delete(strPicFile); else return; } IActiveView pAV = pMap as IActiveView; string sWJLX = strPicFile.Substring(strPicFile.Length - 4).ToUpper(); IExport pExport = null; if (sWJLX == ".TIF") //根據文件名後4位判斷輸出類型 pExport = new ExportTIFFClass(); else if (sWJLX == ".EMF") pExport = new ExportEMFClass(); else if (sWJLX == ".BMP") pExport = new ExportBMPClass(); else if (sWJLX == ".GIF") pExport = new ExportGIFClass(); if (sWJLX == ".PDF") pExport = new ExportPDFClass(); else if (sWJLX == ".PNG") pExport = new ExportPNGClass(); else if (sWJLX == ".SVG") pExport = new ExportSVGClass(); else if (strPicFile.Substring(strPicFile.Length - 4).ToUpper() == ".AI") pExport = new ExportAIClass(); else if (sWJLX == ".EPS") pExport = new ExportPSClass(); else pExport = new ExportJPEGClass(); IDisplayTransformation pDT = pAV.ScreenDisplay.DisplayTransformation; IOutputRasterSettings docOutputRasterSettings = pDT as IOutputRasterSettings; int iPrevOutputImageQuality = docOutputRasterSettings.ResampleRatio; docOutputRasterSettings.ResampleRatio = 1; ////這個似乎沒什麽用 //獲取屏幕dpi /* Get the device context of the screen */ long tmpDC = GetDC(0); /* Get the screen resolution. */ int iScreenResolution = GetDeviceCaps((int)tmpDC, 88); //88 is the win32 const for Logical pixels/inch in X) /* release the DC. */ ReleaseDC(0, (int)tmpDC); // 根據傳入的pExtent確定裁圖的畫布大小(出圖比例尺下裁圖範圍的像素高和寬) tagRECT ptagTmp; ptagTmp.left = 0; //ptagTmp的right和bottom非常主要 ptagTmp.top = 0; ptagTmp.right = (int)Math.Truncate(ConvertMapUnitsToPixels(pAV,pExtent.Width) * iOutResolution / iScreenResolution); //把地圖距離轉為屏幕像素個數 ptagTmp.bottom = (int)Math.Truncate(ConvertMapUnitsToPixels(pAV,pExtent.Height) * iOutResolution / iScreenResolution); IEnvelope pEnvNew = new EnvelopeClass(); pEnvNew.PutCoords(ptagTmp.left,ptagTmp.top,ptagTmp.right,ptagTmp.bottom); //裁圖的畫布大小 pExport.ExportFileName = strPicFile; pExport.Resolution = iOutResolution; pExport.PixelBounds = pEnvNew; if (sWJLX == ".TIF") { (pExport as IExportTIFF).GeoTiff = true;//包含tif文件坐標信息,這2句是必須的 (pExport as IWorldFileSettings).MapExtent = pExtent; (pExport as IExportTIFF).CompressionType = esriTIFFCompression.esriTIFFCompressionJPEG; } if (sWJLX == ".PDF") { (pExport as IExportPDF).Compressed = true; (pExport as IExportPDF).EmbedFonts = true; (pExport as IExportPDF).ImageCompression = esriExportImageCompression.esriExportImageCompressionNone; } int ihdc = pExport.StartExporting(); pAV.Output(ihdc, iOutResolution, ref ptagTmp, pExtent, null); pExport.FinishExporting(); pExport.Cleanup(); (pDT as IOutputRasterSettings).ResampleRatio = iPrevOutputImageQuality; if (!File.Exists(strPicFile) && withWarning) GtMap.GxFrame.GxFrameLib.Common.AxMessageBox.ShowInformation("圖片導出失敗!"); } //created by jhlong http://jhlong12345.blog.163.com/
ArcEngine地圖窗口指定區域導出指定DPI多格式---delphi/C#實現