Technical FAQs

Question

How do I ensure temp files are deleted when closing ImageGear .NET?

Answer

All PDF objects are based on underlying low-level PDF objects that are not controlled by .NET resource manager and garbage collector. Because of this, each PDF object that is created from scratch should be explicitly disposed of using that object’s Dispose() method.

Also, any ImGearPDEContent object obtained from ImGearPDFPage should be released using the ImGearPDFPage.ReleaseContent() in all cases.

This should cause all temp files to be cleared when the application is closed.

Question

I am trying to deploy my ImageGear Pro ActiveX project and am receiving an error stating

The module igPDF18a.ocx failed to load

when registering the igPDF18a.ocx component. Why is this occurring, and how can I register the component correctly?

Answer

To Register your igPDF18a.ocx component you will need to run the following command:

regsvr32 igPDF18a.ocx

If you receive an error stating that the component failed to load, then that likely means that regsvr32 is not finding the necessary dependencies for the PDF component.

The first thing you will want to check is that you have the Microsoft Visual C++ 10.0 CRT (x86) installed on the machine. You can download this from Microsoft’s site here:

https://www.microsoft.com/en-us/download/details.aspx?id=5555

The next thing you will want to check for is the DL100*.dll files. These files should be included in the deployment package generated by the deployment packaging wizard if you included the PDF component when generating the dependencies. These files must be in the same folder as the igPDF18a.ocx component in order to register it.

With those dependencies, you should be able to register the PDF component with regsvr32 without issue.

Question

When printing non-standard size raster images with PrizmDoc they can sometimes become cutoff if too tall or wide. How can I correctly print a non-standard size raster image with PrizmDoc?

Answer

(This explanation is done for a tall portrait image, but can be altered to work for a wide landscape image by flipping the width and height.)

To do this, you have to add a custom paper size to viewerCustomization.js and specify a smaller width so that there is enough room to fit the height of the image on a single page.

To find the correct width value so that the image will fit on a single page, you will need to do some math. In this example, we’ll use an image that is 1305×2823. In this case, the width is 46.2% of the height. If you want to print onto 8.5×11 inch paper, then the width you want to set for your new custom paper size is 11*0.462, which comes out to 5.082.

So now that you have the width, you need to create the new custom paper size. In viewerCustomization.js in the templates section, find the "print" template and add the following code where the other printing paper sizes are located.

/*custom */
.portrait .custom.page { width: 5.082in; height: 11in; margin: 0 auto !important; }
.portrait .custom.pageIE { width: 9.5in; height: 9.5in; margin: 0 auto !important; }
.portrait .custom.pageSafari { width: 8.9in; height: 8.9in; margin: 0 auto !important; }
.portrait .custom.nomargins { width: 11in !important; height: 11in !important; }

/* even without margins, Safari enforces the printer's non-printable area */
.portrait .custom.nomargins.pageSafari { width: 9.32in !important; height: 9.32in !important; }

.landscape .custom.page { height: 5.082in; width: 11in; margin: 0 auto !important; }
.landscape .custom.pageIE { height: 9.05in; width: 9.05in; margin: 0 auto !important; }
.landscape .custom.pageSafari { height: 8.4in; width: 8.4in; margin: 0 auto !important; }
.landscape .custom.nomargins { height: 11in !important; width: 11in !important; }
.landscape .custom.nomargins.pageSafari { height: 9.32in !important; width: 9.32in !important; }
/*custom end*/

As you can see, the width for .portrait .custom.page was set to 5.082in, and the height set to 11in. This will scale the 1305×2823 image to fit on a single 8.5×11 page when printing. By flipping the values and setting them in .landscape you would be able to print a 2823×1305 image on a single landscape page. (Just to note, I only edited the values for .custom.page for portrait and landscape. The others would most likely need to be changed.)

Next you need to add an option for your new paper size to the "paperSize" selection tag in the "printOverlay" section of templates in viewerCustomization.js. Your select tag should end up looking something like this:

<select data-pcc-select="paperSize" class="pcc-print-select">
    <!-- US and International-->
    <option value="letter"><%= paperSizes.letter %></option>
    <option value="legal"><%= paperSizes.legal %></option>
    <option value="tabloid"><%= paperSizes.tabloid %></option>
    <option value="foolscap"><%= paperSizes.foolscap %></option>
    <!-- A formats-->
    <option value="a3"><%= paperSizes.a3 %></option>
    <option value="a4"><%= paperSizes.a4 %></option>
    <option value="a5"><%= paperSizes.a5 %></option>
    <!-- Architectural-->
    <option value="a6"><%= paperSizes.a6 %></option>
    <option value="a"><%= paperSizes.a %></option>
    <option value="b"><%= paperSizes.b %></option>
    <option value="c"><%= paperSizes.c %></option>
    <option value="d"><%= paperSizes.d %></option>
    <option value="e"><%= paperSizes.e %></option>
    <option value="e1"><%= paperSizes.e1 %></option>
        
    <option value="custom">Custom</option>
</select>

The new print option should now appear in the PrizmDoc print settings when selecting a paper size, and it should print the image on a single page.

One thing to note is that you will have to do this for each differently sized image. If you are unsure of the size of uploaded documents, this solution will most likely not be usable.

Question

Using ScanFix Xpress (as illustrated in the ImageCleanUp sample) I can deskew an image, but the leftover blank space is filled with a user-specified pad color, which might clash horribly with the edges of the original image. Is it possible to automatically detect a matching pad color before executing a deskew operation?

Answer

A simple approach would be to crop off the four edges of the image, specified perhaps by a percentage of width/height floor-bound by a minimum pixel count, then use the RGBColorCount method from ImagXpress on each edge to generate a histogram for each color channel, find the most frequent or average intensity (or some combination of the most frequent and the average), and then find the average intensity among all four edges. Then this resultant color could be used as the pad color for the image when it is deskewed.

For example, you can crop out portions of an image using the Crop method of the Processor class…

// Crop out the top edge of the image referred to by proc.Image
Rectangle cropRectangle = new Rectangle(0, 0, inputImg.Width, verticalSliceSize);
_processor.Crop(cropRectangle);
return proc.Image;

We can do this for all four edges of the image. Then, for each edge, we can determine the frequencies at which each intensity occurs in the image’s pixel grid using the RGBColorCount Method…

int[] redHistogram, greenHistogram, blueHistogram;
_processor.Image = edge;
_processor.RGBColorCount(out redHistogram, out greenHistogram, out blueHistogram);

…now, redHistogram, greenHistogram, and blueHistogram will contain the frequencies of red, green, and blue intensities (0 to 255), respectively. We can use this data to extrapolate either the most frequent or the average intensity (or some combination of the two) in each channel. We can then construct RGB triplets representing the detected border color for that edge, and then average the values for each edge to get the appropriate overall pad color. 

For example (using an average intensity)…

public int[] DetectEdgeAverageColor(ImageX edge)
{
    int[] averageRGB = new int[] { 0, 0, 0 };
    int[] redHistogram, greenHistogram, blueHistogram;
    _processor.Image = edge;
    _processor.RGBColorCount(out redHistogram, out greenHistogram, out blueHistogram);

    int numPixels = edge.Width * edge.Height;
    averageRGB[0] = findAverageIntensity(redHistogram, numPixels);
    averageRGB[1] = findAverageIntensity(greenHistogram, numPixels);
    averageRGB[2] = findAverageIntensity(blueHistogram, numPixels);
    

    return averageRGB;
}

private int findAverageIntensity(int[] frequencies, int numPixels)
{
    double averageIntesntity = 0;
    for (int intensityValue = 0; intensityValue < 256; intensityValue++)
    {
        int frequencyOfThisIntesity = frequencies[intensityValue];
        averageIntesntity += (intensityValue * frequencyOfThisIntesity);
    }
    averageIntesntity /= numPixels;
    return (int)Math.Round(averageIntesntity);
}

This should produce an RGB triplet representing a color similar to the edges of the image to be deskewed.