# Cannot change ImageResolution after applying ImagePad

I want to export high-resolution images of a plot I'm making. The trouble is, the plot has a lot of extra white space around it which I get rid of via ImagePad (I could also use ImageCrop but I run into the same problem described here).

If I put in the following code,

tempimage = Plot[x^2, {x, -10, 10}];

Export["testexport100.png", tempimage, ImageResolution -> 100];
Export["testexport125.png", tempimage, ImageResolution -> 125];
Export["testexport150.png", tempimage, ImageResolution -> 150];


I get three files of different size and quality (10KB, 13KB, and 16KB). But when I first adjust the margins of the image, I no longer have the ability to change the resulting image quality. For example, if I do

tempimage2 = ImagePad[tempimage, {{0, -10}, {0, -10}}];

Export["testexport2_100.png", tempimage2, ImageResolution -> 100];
Export["testexport2_125.png", tempimage2, ImageResolution -> 125];
Export["testexport2_150.png", tempimage2, ImageResolution -> 150];


Then all three resulting files are identical and 7KB.

-

Answering your question in comments, there are ways to crop graphics directly, without converting it to raster. For example, using Inset here I cut off 10% of the ImageSize from the right and from the top keeping everything in vector form:

gr = Plot[x^2, {x, -10, 10}];
Graphics[Inset[gr, ImageScaled[{0, 0}], ImageScaled[{0, 0}],
ImageScaled[10/9]], Options[gr, AspectRatio]]


And here I cut off 10 printer's points from the right and from the top:

gr = Plot[x^2, {x, -10, 10}, ImageSize -> {360, 234}];
gr2 = Graphics[
Inset[gr, ImageScaled[{0, 0}], ImageScaled[{0, 0}], Automatic],
ImageSize -> {{0, 360 - 10}, {0, 234 - 10}}, AspectRatio -> Full]


If you just need to display a part of the plot you could set explicit PlotRange to include only the part of the plot you wish to display (but it is not identical to vector cropping). If you need to remove white borders you could try Method -> {"ShrinkWrap" -> True}.

-
Related: "Cropping a plot via a command." –  Alexey Popkov Oct 30 '13 at 18:48
Related: "Cropping a Plot without rasterization." –  Alexey Popkov Mar 8 at 23:08

For whatever reason, the image that results from applying ImagePad or ImageCrop or ImageTrim cannot have its resolution changed. Maybe it's already been rasterized? But I'm able to work around this by rasterizing the image before applying ImagePad. I use the following function to make sure that the amount trimmed off the side is the same that you would get by applying ImagePad to the original.

RasterPad[image_, resolution_, padding_] :=
odims = ImageDimensions[image];
nimage = Rasterize[image, "Image", ImageResolution -> resolution];
ndims = ImageDimensions[nimage];

Export["testexport2_100.png",RasterPad[tempimage,100,{{0,-10},{0,-10}}]];

Surely ImagePad rasterizes the fugure as well as any other Image* function: all these functions are designed to work with raster Images and apply Image in order to get an object they can work with. Note also that even Graphics[Raster[...]] will be rasterized in the same way (generally with loosing quality). –  Alexey Popkov Oct 10 '13 at 1:49
I think you have confused yourself slightly by referring to Graphics expressions as images. Your tempimage is not an Image, it is a Graphics expression. As Alexey notes, when ImagePad receives an argument which is not already an Image it must rasterize it. This rasterization takes place behind the scenes, using default settings. As you have discovered, if the default settings are no good for you, you need to do the rasterization explicitly with your preferred settings instead of having ImagePad do it automatically. –  Simon Woods Oct 10 '13 at 13:38
So yeah, I didn't realize there was a difference between an Image and a Graphics expression. So is there a better way to do what I'm trying to accomplish here? Is there a way to crop a graphics expression directly? –  Jason B Oct 10 '13 at 16:09
@JasonB This depends on what you really want. You can always set PlotRangePadding -> None and set explicit PlotRange to include only the part of the plot you wish to display. If you need to remove white borders you could try Method -> {"ShrinkWrap" -> True}. –  Alexey Popkov Oct 11 '13 at 1:50