ArcEngine地圖視窗指定區域匯出指定DPI多格式---delphi/C#實現

weixin_34321977發表於2016-04-15
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/

 

 

相關文章