PDFページをプログラムでトリミングする C#
ページプロパティの取得
PDFファイルの各ページには、幅、高さ、ブリード、クロップ、トリムボックスなどのプロパティがあります。Aspose.PDFを使用すると、これらのプロパティにアクセスできます。
メディアボックス : メディアボックスは、最も大きなページボックスです。これは、文書がPostScriptまたはPDFに印刷されたときに選択されたページサイズ(例えばA4、A5、USレターなど)に対応します。言い換えれば、メディアボックスはPDF文書が表示または印刷されるメディアの物理的なサイズを決定します。
ブリードボックス : 文書にブリードがある場合、PDFにもブリードボックスがあります。ブリードは、ページの端を超えて延びる色(またはアートワーク)の量です。これは、文書が印刷され、サイズにカット(「トリム」)されるときに、インクがページの端まで届くことを保証するために使用されます。たとえページがトリムマークからわずかに外れてカットされても、ページに白いエッジは現れません。
トリムボックス : トリムボックスは、印刷およびトリミング後の文書の最終サイズを示します。
アートボックス : アートボックスは、文書内のページの実際の内容の周りに描かれたボックスです。このページボックスは、他のアプリケーションでPDF文書をインポートする際に使用されます。
クロップボックス : クロップボックスは、Adobe AcrobatでPDF文書が表示される「ページ」サイズです。通常の表示では、Adobe Acrobatではクロップボックスの内容のみが表示されます。これらのプロパティの詳細な説明については、Adobe.Pdf仕様書、特に10.10.1ページ境界を参照してください。
Page.Rect : メディアボックスとドロップボックスの交差点(一般的に見える長方形)です。以下の図はこれらのプロパティを示しています。
詳細については、このページ をご覧ください。
以下のコードスニペットは、Aspose.PDF.Drawing ライブラリでも動作します。
以下のスニペットは、ページをトリミングする方法を示しています:
Copy
private static void CropPage ( )
{
var dataDir = RunExamples . GetDataDir_AsposePdf_Pages ();
using ( var document = new Aspose . Pdf . Document ( dataDir + "CropPageInput.pdf" ))
{
Console . WriteLine ( document . Pages [ 1 ]. CropBox );
Console . WriteLine ( document . Pages [ 1 ]. TrimBox );
Console . WriteLine ( document . Pages [ 1 ]. ArtBox );
Console . WriteLine ( document . Pages [ 1 ]. BleedBox );
Console . WriteLine ( document . Pages [ 1 ]. MediaBox );
var newBox = new Rectangle ( 200 , 220 , 2170 , 1520 );
document . Pages [ 1 ]. CropBox = newBox ;
document . Pages [ 1 ]. TrimBox = newBox ;
document . Pages [ 1 ]. ArtBox = newBox ;
document . Pages [ 1 ]. BleedBox = newBox ;
document . Save ( dataDir + "CropPage_out.pdf" );
}
}
この例では、サンプルファイルをこちら で使用しました。最初に私たちのページは図1のように見えます。
変更後、ページは図2のように見えます。
ページの周りの白いスペースをトリミングする
たとえば、ビットマップを読み込むことができる任意のグラフィックスライブラリを使用して、ページの周りの白いスペースをトリミングできます:
.NET Core 3.1
Copy
private static void TrimWhiteSpaceAroundPage ( )
{
var dataDir = RunExamples . GetDataDir_AsposePdf_Pages ();
using ( var document = new Aspose . Pdf . Document ( dataDir + "TrimWhiteSpaceAroundPage.pdf" ))
{
var device = new Aspose . Pdf . Devices . PngDevice ( new Aspose . Pdf . Devices . Resolution ( 300 ));
using ( var imageStr = new MemoryStream ())
{
device . Process ( document . Pages [ 1 ], imageStr );
using ( var pageBitmap = new Bitmap ( imageStr ))
{
document . Pages [ 1 ]. CropBox = GetNewCropBox ( pageBitmap , document . Pages [ 1 ]. CropBox );
}
}
document . Save ( dataDir + "TrimWhiteSpaceAroundPage_out.pdf" );
}
}
private static Aspose . Pdf . Rectangle GetNewCropBox ( Bitmap pageBitmap , Aspose . Pdf . Rectangle prevCropBox )
{
var imageBitmapData = pageBitmap . LockBits ( new Rectangle ( 0 , 0 , pageBitmap . Width , pageBitmap . Height ),
ImageLockMode . ReadOnly , PixelFormat . Format32bppRgb );
int toHeight = pageBitmap . Height ;
int toWidth = pageBitmap . Width ;
int ? leftNonWhite = null ;
int ? rightNonWhite = null ;
int ? topNonWhite = null ;
int ? bottomNonWhite = null ;
var imageRowBytes = new byte [ imageBitmapData . Stride ];
for ( int y = 0 ; y < toHeight ; y ++)
{
if ( IntPtr . Size == 4 )
{
Marshal . Copy ( new IntPtr ( imageBitmapData . Scan0 . ToInt32 () + y * imageBitmapData . Stride ), imageRowBytes , 0 , imageBitmapData . Stride );
}
else
{
Marshal . Copy ( new IntPtr ( imageBitmapData . Scan0 . ToInt64 () + y * imageBitmapData . Stride ), imageRowBytes , 0 , imageBitmapData . Stride );
}
int ? leftNonWhite_row = null ;
int ? rightNonWhite_row = null ;
for ( int x = 0 ; x < toWidth ; x ++)
{
if ( imageRowBytes [ x * 4 ] != 255
|| imageRowBytes [ x * 4 + 1 ] != 255
|| imageRowBytes [ x * 4 + 2 ] != 255 )
{
if ( leftNonWhite_row == null )
{
leftNonWhite_row = x ;
}
rightNonWhite_row = x ;
}
}
if ( leftNonWhite_row != null || rightNonWhite_row != null )
{
if ( topNonWhite == null )
{
topNonWhite = y ;
}
bottomNonWhite = y ;
}
if ( leftNonWhite_row != null
&& ( leftNonWhite == null || leftNonWhite > leftNonWhite_row ))
{
leftNonWhite = leftNonWhite_row ;
}
if ( rightNonWhite_row != null
&& ( rightNonWhite == null || rightNonWhite < rightNonWhite_row ))
{
rightNonWhite = rightNonWhite_row ;
}
}
leftNonWhite = leftNonWhite ?? 0 ;
rightNonWhite = rightNonWhite ?? toWidth ;
topNonWhite = topNonWhite ?? 0 ;
bottomNonWhite = bottomNonWhite ?? toHeight ;
double xCoef = prevCropBox . Width / toWidth ;
double yCoef = prevCropBox . Height / toHeight ;
pageBitmap . UnlockBits ( imageBitmapData );
return
new Aspose . Pdf . Rectangle (
leftNonWhite . Value * xCoef + prevCropBox . LLX ,
( toHeight * yCoef + prevCropBox . LLY ) - bottomNonWhite . Value * yCoef ,
rightNonWhite . Value * xCoef + prevCropBox . LLX ,
( toHeight * yCoef + prevCropBox . LLY ) - topNonWhite . Value * yCoef
);
}
.NET 8
Copy
private static void TrimWhiteSpaceAroundPage ( )
{
var dataDir = RunExamples . GetDataDir_AsposePdf_Pages ();
using var document = new Aspose . Pdf . Document ( dataDir + "TrimWhiteSpaceAroundPage.pdf" );
var device = new Aspose . Pdf . Devices . PngDevice ( new Aspose . Pdf . Devices . Resolution ( 300 ));
using var imageStr = new MemoryStream ();
device . Process ( document . Pages [ 1 ], imageStr );
using var pageBitmap = new Bitmap ( imageStr );
document . Pages [ 1 ]. CropBox = GetNewCropBox ( pageBitmap , document . Pages [ 1 ]. CropBox );
document . Save ( dataDir + "TrimWhiteSpaceAroundPage_out.pdf" );
}
private static Aspose . Pdf . Rectangle GetNewCropBox ( Bitmap pageBitmap , Aspose . Pdf . Rectangle prevCropBox )
{
var imageBitmapData = pageBitmap . LockBits ( new Rectangle ( 0 , 0 , pageBitmap . Width , pageBitmap . Height ),
ImageLockMode . ReadOnly , PixelFormat . Format32bppRgb );
int toHeight = pageBitmap . Height ;
int toWidth = pageBitmap . Width ;
int ? leftNonWhite = null ;
int ? rightNonWhite = null ;
int ? topNonWhite = null ;
int ? bottomNonWhite = null ;
var imageRowBytes = new byte [ imageBitmapData . Stride ];
for ( int y = 0 ; y < toHeight ; y ++)
{
if ( IntPtr . Size == 4 )
{
Marshal . Copy ( new IntPtr ( imageBitmapData . Scan0 . ToInt32 () + y * imageBitmapData . Stride ), imageRowBytes , 0 , imageBitmapData . Stride );
}
else
{
Marshal . Copy ( new IntPtr ( imageBitmapData . Scan0 . ToInt64 () + y * imageBitmapData . Stride ), imageRowBytes , 0 , imageBitmapData . Stride );
}
int ? leftNonWhite_row = null ;
int ? rightNonWhite_row = null ;
for ( int x = 0 ; x < toWidth ; x ++)
{
if ( imageRowBytes [ x * 4 ] != 255
|| imageRowBytes [ x * 4 + 1 ] != 255
|| imageRowBytes [ x * 4 + 2 ] != 255 )
{
if ( leftNonWhite_row == null )
{
leftNonWhite_row = x ;
}
rightNonWhite_row = x ;
}
}
if ( leftNonWhite_row != null || rightNonWhite_row != null )
{
if ( topNonWhite == null )
{
topNonWhite = y ;
}
bottomNonWhite = y ;
}
if ( leftNonWhite_row != null
&& ( leftNonWhite == null || leftNonWhite > leftNonWhite_row ))
{
leftNonWhite = leftNonWhite_row ;
}
if ( rightNonWhite_row != null
&& ( rightNonWhite == null || rightNonWhite < rightNonWhite_row ))
{
rightNonWhite = rightNonWhite_row ;
}
}
leftNonWhite = leftNonWhite ?? 0 ;
rightNonWhite = rightNonWhite ?? toWidth ;
topNonWhite = topNonWhite ?? 0 ;
bottomNonWhite = bottomNonWhite ?? toHeight ;
double xCoef = prevCropBox . Width / toWidth ;
double yCoef = prevCropBox . Height / toHeight ;
pageBitmap . UnlockBits ( imageBitmapData );
return
new Aspose . Pdf . Rectangle (
leftNonWhite . Value * xCoef + prevCropBox . LLX ,
( toHeight * yCoef + prevCropBox . LLY ) - bottomNonWhite . Value * yCoef ,
rightNonWhite . Value * xCoef + prevCropBox . LLX ,
( toHeight * yCoef + prevCropBox . LLY ) - topNonWhite . Value * yCoef
);
}