您的位置:首页 > 编程语言 > Delphi

ArcEngine地图窗口指定区域导出指定DPI多格式---delphi/C#实现

2016-04-15 10:47 751 查看
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/[/code] 
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: