Created
January 12, 2016 12:48
-
-
Save george-silva/8784d35857bfb778e80d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
using System.Text; | |
using ESRI.ArcGIS.Carto; | |
using ESRI.ArcGIS.Display; | |
using ESRI.ArcGIS.Geometry; | |
using ESRI.ArcGIS.Output; | |
using ESRI.ArcGIS.esriSystem; | |
namespace OptimusGIS.MapGenerator.PrintEngine | |
{ | |
/// <summary> | |
/// Classe responsável por exportar os resultados de um layout para | |
/// uma imagem em disco. | |
/// </summary> | |
public class FileRenderer | |
{ | |
[DllImport("GDI32.dll")] | |
public static extern int GetDeviceCaps(int hdc, int nIndex); | |
[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)] | |
private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref int pvParam, uint fWinIni); | |
private const uint SPI_GETFONTSMOOTHING = 74; | |
private const uint SPI_SETFONTSMOOTHING = 75; | |
private const uint SPIF_UPDATEINIFILE = 0x1; | |
public static void ExportActiveViewParameterized(IActiveView view, | |
long outputResolution, | |
long resampleRatio, | |
string exportType, | |
string fileName, | |
Boolean clipToExtent) | |
{ | |
try | |
{ | |
IActiveView docActiveView = view; | |
IExport docExport; | |
long previousOutputQuality; | |
IOutputRasterSettings docOutputRasterSettings; | |
IEnvelope PixelBoundsEnv; | |
tagRECT exportRECT; | |
tagRECT DisplayBounds; | |
IDisplayTransformation docDisplayTransformation; | |
IPageLayout docPageLayout; | |
IEnvelope docMapExtEnv; | |
long hdc; | |
long tmpDC; | |
long iScreenResolution; | |
IEnvelope docGraphicsExtentEnv; | |
IUnitConverter unitConverter; | |
switch (exportType) | |
{ | |
case "PDF": | |
docExport = new ExportPDFClass(); | |
break; | |
case "EPS": | |
docExport = new ExportPSClass(); | |
break; | |
case "AI": | |
docExport = new ExportAIClass(); | |
break; | |
case "BMP": | |
docExport = new ExportBMPClass(); | |
break; | |
case "TIFF": | |
docExport = new ExportTIFFClass(); | |
break; | |
case "SVG": | |
docExport = new ExportSVGClass(); | |
break; | |
case "PNG": | |
docExport = new ExportPNGClass(); | |
break; | |
case "GIF": | |
docExport = new ExportGIFClass(); | |
break; | |
case "EMF": | |
docExport = new ExportEMFClass(); | |
break; | |
case "JPG": | |
docExport = new ExportJPEGClass(); | |
break; | |
default: | |
exportType = "EMF"; | |
docExport = new ExportEMFClass(); | |
break; | |
} | |
// save the previous output image quality, so that when the export is complete it will be set back. | |
docOutputRasterSettings = docActiveView.ScreenDisplay.DisplayTransformation as IOutputRasterSettings; | |
previousOutputQuality = docOutputRasterSettings.ResampleRatio; | |
if (docExport is IExportImage) | |
// always set the output quality of the DISPLAY to 1 for image export formats | |
SetOutputQuality(docActiveView, 1); | |
else | |
// for vector formats, assign the desired ResampleRatio to control drawing of raster layers at export time | |
SetOutputQuality(docActiveView, resampleRatio); | |
// set the export filename (which is the nameroot + the appropriate file extension) | |
docExport.ExportFileName = fileName; | |
/* Get the device context of the screen */ | |
tmpDC = GetDC(0); | |
/* Get the screen resolution. */ | |
iScreenResolution = GetDeviceCaps((int)tmpDC, 88); | |
//88 is the win32 const for Logical pixels/inch in X) | |
/* release the DC. */ | |
ReleaseDC(0, (int)tmpDC); | |
docExport.Resolution = outputResolution; | |
if (docActiveView is IPageLayout) | |
{ | |
//get the bounds of the "exportframe" of the active view. | |
DisplayBounds = docActiveView.ExportFrame; | |
//set up pGraphicsExtent, used if clipping to graphics extent. | |
docGraphicsExtentEnv = GetGraphicsExtent(docActiveView); | |
} | |
else | |
{ | |
//Get the bounds of the deviceframe for the screen. | |
docDisplayTransformation = docActiveView.ScreenDisplay.DisplayTransformation; | |
DisplayBounds = docDisplayTransformation.get_DeviceFrame(); | |
} | |
PixelBoundsEnv = new Envelope() as IEnvelope; | |
if (clipToExtent && (docActiveView is IPageLayout)) | |
{ | |
docGraphicsExtentEnv = GetGraphicsExtent(docActiveView); | |
docPageLayout = docActiveView as PageLayout; | |
unitConverter = new UnitConverter(); | |
//assign the x and y values representing the clipped area to the PixelBounds envelope | |
PixelBoundsEnv.XMin = 0; | |
PixelBoundsEnv.YMin = 0; | |
PixelBoundsEnv.XMax = | |
unitConverter.ConvertUnits(docGraphicsExtentEnv.XMax, docPageLayout.Page.Units, | |
esriUnits.esriInches) * docExport.Resolution - | |
unitConverter.ConvertUnits(docGraphicsExtentEnv.XMin, docPageLayout.Page.Units, | |
esriUnits.esriInches) * docExport.Resolution; | |
PixelBoundsEnv.YMax = | |
unitConverter.ConvertUnits(docGraphicsExtentEnv.YMax, docPageLayout.Page.Units, | |
esriUnits.esriInches) * docExport.Resolution - | |
unitConverter.ConvertUnits(docGraphicsExtentEnv.YMin, docPageLayout.Page.Units, | |
esriUnits.esriInches) * docExport.Resolution; | |
//'assign the x and y values representing the clipped export extent to the exportRECT | |
exportRECT.bottom = (int)(PixelBoundsEnv.YMax) + 1; | |
exportRECT.left = (int)(PixelBoundsEnv.XMin); | |
exportRECT.top = (int)(PixelBoundsEnv.YMin); | |
exportRECT.right = (int)(PixelBoundsEnv.XMax) + 1; | |
//since we're clipping to graphics extent, set the visible bounds. | |
docMapExtEnv = docGraphicsExtentEnv; | |
} | |
else | |
{ | |
double tempratio = outputResolution / iScreenResolution; | |
double tempbottom = DisplayBounds.bottom * tempratio; | |
double tempright = DisplayBounds.right * tempratio; | |
//'The values in the exportRECT tagRECT correspond to the width | |
//and height to export, measured in pixels with an origin in the top left corner. | |
exportRECT.bottom = (int)Math.Truncate(tempbottom); | |
exportRECT.left = 0; | |
exportRECT.top = 0; | |
exportRECT.right = (int)Math.Truncate(tempright); | |
//populate the PixelBounds envelope with the values from exportRECT. | |
// We need to do this because the exporter object requires an envelope object | |
// instead of a tagRECT structure. | |
PixelBoundsEnv.PutCoords(exportRECT.left, exportRECT.top, exportRECT.right, exportRECT.bottom); | |
//since it's a page layout or an unclipped page layout we don't need docMapExtEnv. | |
docMapExtEnv = null; | |
} | |
// Assign the envelope object to the exporter object's PixelBounds property. The exporter object | |
// will use these dimensions when allocating memory for the export file. | |
docExport.PixelBounds = PixelBoundsEnv; | |
// call the StartExporting method to tell docExport you're ready to start outputting. | |
hdc = docExport.StartExporting(); | |
// Redraw the active view, rendering it to the exporter object device context instead of the app display. | |
// We pass the following values: | |
// * hDC is the device context of the exporter object. | |
// * exportRECT is the tagRECT structure that describes the dimensions of the view that will be rendered. | |
// The values in exportRECT should match those held in the exporter object's PixelBounds property. | |
// * docMapExtEnv is an envelope defining the section of the original image to draw into the export object. | |
docActiveView.Output((int)hdc, (int)docExport.Resolution, ref exportRECT, docMapExtEnv, null); | |
//finishexporting, then cleanup. | |
docExport.FinishExporting(); | |
docExport.Cleanup(); | |
//set the output quality back to the previous value | |
SetOutputQuality(docActiveView, previousOutputQuality); | |
docMapExtEnv = null; | |
PixelBoundsEnv = null; | |
} | |
catch (Exception ex) | |
{ | |
System.Diagnostics.Debug.WriteLine(ex.Message); | |
throw; | |
} | |
finally | |
{ | |
EnableFontSmoothing(); | |
} | |
} | |
/// <summary> | |
/// Sets OutputImageQuality for activeview. If this is pageLayout, set | |
/// output image quality for each data frame. | |
/// </summary> | |
/// <param name="docActiveView"></param> | |
/// <param name="iResampleRatio"></param> | |
private static void SetOutputQuality(IActiveView docActiveView, long iResampleRatio) | |
{ | |
IGraphicsContainer oiqGraphicsContainer; | |
IElement oiqElement; | |
IOutputRasterSettings docOutputRasterSettings; | |
IMapFrame docMapFrame; | |
IActiveView tempActiveView; | |
if (docActiveView is IMap) | |
{ | |
docOutputRasterSettings = docActiveView.ScreenDisplay.DisplayTransformation as IOutputRasterSettings; | |
docOutputRasterSettings.ResampleRatio = (int) iResampleRatio; | |
} | |
else if (docActiveView is IPageLayout) | |
{ | |
//assign ResampleRatio for PageLayout | |
docOutputRasterSettings = docActiveView.ScreenDisplay.DisplayTransformation as IOutputRasterSettings; | |
docOutputRasterSettings.ResampleRatio = (int) iResampleRatio; | |
//and assign ResampleRatio to the Maps in the PageLayout | |
oiqGraphicsContainer = docActiveView as IGraphicsContainer; | |
oiqGraphicsContainer.Reset(); | |
oiqElement = oiqGraphicsContainer.Next(); | |
while (oiqElement != null) | |
{ | |
if (oiqElement is IMapFrame) | |
{ | |
docMapFrame = (IMapFrame) oiqElement; | |
tempActiveView = (IActiveView) docMapFrame.Map; | |
docOutputRasterSettings = tempActiveView.ScreenDisplay.DisplayTransformation as IOutputRasterSettings; | |
docOutputRasterSettings.ResampleRatio = (int) iResampleRatio; | |
} | |
oiqElement = oiqGraphicsContainer.Next(); | |
} | |
docMapFrame = null; | |
oiqGraphicsContainer = null; | |
tempActiveView = null; | |
} | |
docOutputRasterSettings = null; | |
} | |
/// <summary> | |
/// This method gets the extent of all objects in the map | |
/// </summary> | |
/// <param name="docActiveView"></param> | |
/// <returns></returns> | |
private static IEnvelope GetGraphicsExtent(IActiveView docActiveView) | |
{ | |
IEnvelope GraphicsBounds; | |
IEnvelope GraphicsEnvelope; | |
IGraphicsContainer oiqGraphicsContainer; | |
IPageLayout docPageLayout; | |
IDisplay GraphicsDisplay; | |
IElement oiqElement; | |
GraphicsBounds = new EnvelopeClass(); | |
GraphicsEnvelope = new EnvelopeClass(); | |
docPageLayout = docActiveView as IPageLayout; | |
GraphicsDisplay = docActiveView.ScreenDisplay; | |
oiqGraphicsContainer = docActiveView as IGraphicsContainer; | |
oiqGraphicsContainer.Reset(); | |
oiqElement = oiqGraphicsContainer.Next(); | |
while (oiqElement != null) | |
{ | |
oiqElement.QueryBounds(GraphicsDisplay, GraphicsEnvelope); | |
GraphicsBounds.Union(GraphicsEnvelope); | |
oiqElement = oiqGraphicsContainer.Next(); | |
} | |
return GraphicsBounds; | |
} | |
/// <summary> | |
/// Disable font smoothing | |
/// </summary> | |
private static void DisableFontSmoothing() | |
{ | |
bool iResult; | |
int pv = 0; | |
/* call to systemparametersinfo to set the font smoothing value */ | |
iResult = SystemParametersInfo(SPI_SETFONTSMOOTHING, 0, ref pv, SPIF_UPDATEINIFILE); | |
} | |
/// <summary> | |
/// Enable font smoothing | |
/// </summary> | |
private static void EnableFontSmoothing() | |
{ | |
bool iResult; | |
int pv = 0; | |
iResult = SystemParametersInfo(SPI_SETFONTSMOOTHING, 1, ref pv, SPIF_UPDATEINIFILE); | |
} | |
/// <summary> | |
/// Gets if the font smoothing is enabled | |
/// </summary> | |
/// <returns></returns> | |
private static Boolean GetFontSmoothing() | |
{ | |
bool iResult; | |
int pv = 0; | |
/* call to systemparametersinfo to get the font smoothing value */ | |
iResult = SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, ref pv, 0); | |
return pv > 0; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment