IRasterGridDecoder, поддерживающий большие изображения"/>
/// <summary>
/// Provides the image decoder for IRasterGridDecoder example.
/// </summary>
public class RasterGridDecoderExample : Vintasoft.Imaging.Codecs.Decoders.DecoderBase, Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder
{
#region Constants
/// <summary>
/// The rect decoding time, in milliseconds (emulate image decoding).
/// </summary>
private const int RectDecodingTimeMs = 1;
#endregion
#region Fields
/// <summary>
/// The list with information about pages.
/// </summary>
List<RasterGridPageMetadata> _pageInfos = new List<RasterGridPageMetadata>();
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="RasterGridDecoderExample"/> class.
/// </summary>
/// <remarks>
/// This constructor is used in <see cref="T:Vintasoft.Imaging.Codecs.Decoders.AvailableDecoders" /> and
/// should not be used in real applications.
/// </remarks>
public RasterGridDecoderExample()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RasterGridDecoderExample"/> class.
/// </summary>
/// <param name="stream">The stream, which stores raw data of image/document source.</param>
public RasterGridDecoderExample(Stream stream)
: base(stream)
{
if (!IsValidFormat(stream))
throw new NotSupportedException();
StreamReader reader = new StreamReader(stream);
while (!reader.EndOfStream)
{
_pageInfos.Add(RasterGridPageMetadata.Parse(reader));
}
}
#endregion
#region Properties
/// <summary>
/// Gets the name of the decoder.
/// </summary>
public override string Name
{
get
{
return RasterGridCodecExample.CodecName;
}
}
#endregion
#region Methods
#region PUBLIC
/// <summary>
/// Determines that decoder can read a region of the image.
/// </summary>
/// <param name="scale">The rect scale.</param>
/// <param name="pageIndex">The zero based page index.</param>
/// <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
/// <returns>
/// <b>True</b> if decoder can read a region of the image;<br /><b>false</b> if decoder can read only rectangle of the image.
/// </returns>
/// <remarks>
/// <i>Region</i> represents a rectangular region on the image and
/// composed from a sequence of rectangles.
/// </remarks>
public bool CanReadImageRegion(int pageIndex, int scale, Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings)
{
return _pageInfos[pageIndex].CanReadImageRegion;
}
/// <summary>
/// Determines that decoder can progressively read the image.
/// </summary>
/// <param name="pageIndex">The zero based page index.</param>
/// <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
/// <returns>
/// <b>True</b> if decoder can progressively read the image;<br /><b>false</b> if decoder cannot progressively read the image.
/// </returns>
public bool CanUseProgressiveDecoding(int pageIndex, Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings)
{
return false;
}
/// <summary>
/// Returns an image, which is associated with the specified page of image/document source.
/// </summary>
/// <param name="pageIndex">The zero-based page index in image/document source.</param>
/// <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
/// <param name="renderingSettings">Rendering settings used for rendering the image of page.
/// This parameter has effect only if <see cref="P:Vintasoft.Imaging.Codecs.Decoders.DecoderBase.IsVectorDecoder" /> property is equal to <b>True</b>.</param>
/// <param name="progressDelegate">Progress delegate.</param>
/// <returns>
/// Rendered image, which is associated with the specified page of image/document source, if decoder supports rendering;
/// otherwise, image associated with the specified page of the image source.
/// </returns>
public override Vintasoft.Imaging.VintasoftImage GetImage(int pageIndex,
Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings,
Vintasoft.Imaging.Codecs.Decoders.RenderingSettings renderingSettings,
EventHandler<Vintasoft.Imaging.ProgressEventArgs> progressDelegate)
{
throw new NotSupportedException();
}
/// <summary>
/// Returns information about image without loading the image data into memory.
/// </summary>
/// <param name="pageIndex">The zero-based page index in image/document source.</param>
/// <param name="renderingSettings">Rendering settings used for getting info about the image of page.
/// This parameter has effect only if <see cref="P:Vintasoft.Imaging.Codecs.Decoders.DecoderBase.IsVectorDecoder" /> property is equal to <b>True</b>.</param>
/// <param name="decodingSettings">decoding settings used for getting info about the image of page.</param>
/// <returns>
/// Information about the image associated with the page of the source image.
/// </returns>
public override Vintasoft.Imaging.Codecs.Decoders.ImageInfo GetImageInfo(int pageIndex,
Vintasoft.Imaging.Codecs.Decoders.RenderingSettings renderingSettings,
Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings)
{
RasterGridPageMetadata pageInfo = _pageInfos[pageIndex];
return new Vintasoft.Imaging.Codecs.Decoders.ImageInfo(
pageInfo.ImageWidth, pageInfo.ImageHeight, pageInfo.BitsPerPixel, new Vintasoft.Imaging.Palette(), pageInfo.Resolution);
}
/// <summary>
/// Returns a scaled rectangle of raster image.
/// </summary>
/// <param name="pageIndex">The zero based page index.</param>
/// <param name="rectIndex">The zero based the rectangle index.</param>
/// <param name="scale">Scale factor. Possible values: 1 - original image rect should
/// be get; N - reduced image rect should be get.</param>
/// <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
/// <param name="imageLoadingProgress">Delegate of the image loading progress.
/// Can be set to <b>null</b> (<b>Nothing</b> in Visual Basic).</param>
/// <param name="intermediateImageRequest">Delegate for requesting intermediate image.
/// Can be set to <b>null</b> (<b>Nothing</b> in Visual Basic)</param>
/// <returns>
/// Scaled rectangle of image.
/// </returns>
public Vintasoft.Imaging.VintasoftImage GetImageRect(int pageIndex, int rectIndex, int scale,
Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings,
EventHandler<Vintasoft.Imaging.ProgressEventArgs> imageLoadingProgress,
EventHandler<Vintasoft.Imaging.ImageRendering.IntermediateImageRequestEventArgs> intermediateImageRequest)
{
RasterGridPageMetadata pageInfo = _pageInfos[pageIndex];
Rectangle[] grid = GetImageRectGrid(pageIndex, decodingSettings);
Rectangle rect = grid[rectIndex];
Vintasoft.Imaging.VintasoftImage image = CreateImage(rect.Width, rect.Height, scale, pageInfo);
DrawTileInfo(image, $"{rectIndex}\n1/{scale}", scale);
// emulate image decoding
if (RectDecodingTimeMs > 0)
System.Threading.Thread.Sleep(RectDecodingTimeMs);
return image;
}
/// <summary>
/// Returns a scaled region of raster image.
/// </summary>
/// <param name="pageIndex">The zero based page index.</param>
/// <param name="leftTopRectIndex">The zero based index of left-top rectangle.</param>
/// <param name="rightBottomRectIndex">The zero based index of right-bottom rectangle.</param>
/// <param name="scale">Scale factor. Possible values: 1 - original image rect should
/// be get; N - reduced image rect should be get.</param>
/// <param name="decodingSettings">Decoding settings.</param>
/// <param name="imageLoadingProgress">Delegate of the image loading progress.
/// Can be set to <b>null</b> (<b>Nothing</b> in Visual Basic).</param>
/// <param name="intermediateImageRequest">Delegate for requesting intermediate image.
/// Can be set to <b>null</b> (<b>Nothing</b> in Visual Basic)</param>
/// <returns>
/// Scaled region of image.
/// </returns>
public Vintasoft.Imaging.VintasoftImage GetImageRegion(int pageIndex, int leftTopRectIndex, int rightBottomRectIndex, int scale,
Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings, EventHandler<Vintasoft.Imaging.ProgressEventArgs> imageLoadingProgress,
EventHandler<Vintasoft.Imaging.ImageRendering.IntermediateImageRequestEventArgs> intermediateImageRequest)
{
RasterGridPageMetadata pageInfo = _pageInfos[pageIndex];
Rectangle[] grid = GetImageRectGrid(pageIndex, decodingSettings);
Rectangle leftTopRect = grid[leftTopRectIndex];
Rectangle rightBottomRect = grid[rightBottomRectIndex];
Rectangle rect = new Rectangle(
leftTopRect.X,
leftTopRect.Y,
rightBottomRect.X + rightBottomRect.Width - leftTopRect.X,
rightBottomRect.Y + rightBottomRect.Height - leftTopRect.Y);
Vintasoft.Imaging.VintasoftImage image = CreateImage(rect.Width, rect.Height, scale, pageInfo);
DrawTileInfo(image, $"{leftTopRectIndex}:{rightBottomRectIndex}\n1/{scale}", scale);
// emulate image decoding
if (RectDecodingTimeMs > 0)
System.Threading.Thread.Sleep(RectDecodingTimeMs);
return image;
}
/// <summary>
/// Returns an image grid as array of rectangles.
/// </summary>
/// <param name="pageIndex">The zero based page index.</param>
/// <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
/// <returns>
/// An image grid as array of rectangles.
/// </returns>
/// <remarks>
/// Method must return an array with one rectangle which size is equal to the size
/// of image if decoder cannot get image by parts.
/// </remarks>
public Rectangle[] GetImageRectGrid(int pageIndex, Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings)
{
RasterGridPageMetadata pageInfo = _pageInfos[pageIndex];
return SplitIntoTileRectangles(new Size(pageInfo.ImageWidth, pageInfo.ImageHeight), new Size(pageInfo.TileWidth, pageInfo.TileHeight));
}
/// <summary>
/// Returns an array of scale factors for rectangles of image grid.
/// </summary>
/// <param name="pageIndex">The zero based page index.</param>
/// <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
/// <returns>
/// An array of scale factors for rectangles of image grid.
/// </returns>
/// <remarks>
/// Possible values of scale factor:
/// <ul><li>1 - decoder can return image rectangle without scaling</li><li>N - decoder can return an image rectangle reduced N times</li></ul>
/// </remarks>
public int[] GetImageRectScales(int pageIndex, Vintasoft.Imaging.Codecs.Decoders.DecodingSettings decodingSettings)
{
return _pageInfos[pageIndex].TileScales;
}
/// <summary>
/// Returns a metadata of specified page of image/document source.
/// </summary>
/// <param name="pageIndex">The zero-based page index in image/document source.</param>
/// <returns>
/// A metadata of specified page of image/document source.
/// </returns>
public override Vintasoft.Imaging.Metadata.PageMetadata GetPageMetadata(int pageIndex)
{
return _pageInfos[pageIndex];
}
/// <summary>
/// Determines that stream contains image file in format of this decoder.
/// </summary>
/// <param name="stream">Stream with binary data of the image file.</param>
/// <returns>
/// <b>True</b> if stream contains image file in format of this decoder; otherwise, <b>false</b>.
/// </returns>
public override bool IsValidFormat(Stream stream)
{
string name = Name;
int index = 0;
while (stream.ReadByte() != (byte)name[0])
{
if (index++ > 5)
return false;
}
stream.Position--;
byte[] bytes = new byte[name.Length];
stream.Read(bytes, 0, bytes.Length);
for (int i = 0; i < bytes.Length; i++)
{
if (bytes[i] != (byte)name[i])
return false;
}
return true;
}
#endregion
#region PROTECTED
/// <summary>
/// Returns the number of pages in the source file stream.
/// </summary>
/// <returns>
/// The number of pages in the source file stream.
/// </returns>
protected override int GetPageCount()
{
return _pageInfos.Count;
}
#endregion
#region PRIVATE
/// <summary>
/// Splits an image area into tile rectangles.
/// </summary>
/// <param name="imageSize">Size of the image.</param>
/// <param name="tileSize">Size of the tile.</param>
/// <returns>
/// An image grid as array of rectangles.
/// </returns>
private static Rectangle[] SplitIntoTileRectangles(Size imageSize, Size tileSize)
{
List<Rectangle> rectangles = new List<Rectangle>();
int rows = (int)Math.Ceiling((double)imageSize.Height / tileSize.Height);
int cols = (int)Math.Ceiling((double)imageSize.Width / tileSize.Width);
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
int width = tileSize.Width;
int height = tileSize.Height;
if (col == cols - 1)
width = imageSize.Width - col * tileSize.Width;
if (row == rows - 1)
height = imageSize.Height - row * tileSize.Height;
rectangles.Add(new Rectangle(col * tileSize.Width, row * tileSize.Height, width, height));
}
}
return rectangles.ToArray();
}
/// <summary>
/// Draws the tile information.
/// </summary>
/// <param name="image">The image.</param>
/// <param name="tileInfo">The tile information.</param>
/// <param name="scale">The scale.</param>
private void DrawTileInfo(Vintasoft.Imaging.VintasoftImage image, string tileInfo, int scale)
{
using (Vintasoft.Imaging.Drawing.DrawingEngine graphics = image.CreateDrawingEngine())
{
graphics.Clear(Color.White);
using (Vintasoft.Imaging.Drawing.IDrawingFont font = graphics.DrawingFactory.CreateDefaultFont(Math.Max(10, 180f / scale)))
using (Vintasoft.Imaging.Drawing.IDrawingBrush brush = graphics.DrawingFactory.CreateSolidBrush(Color.Black))
{
graphics.DrawText(tileInfo, font, brush, new RectangleF(0, 0, image.Width, image.Height),
new Vintasoft.Imaging.Drawing.TextLayoutProperties(Vintasoft.Imaging.AnchorType.Center, true));
}
using (Vintasoft.Imaging.Drawing.IDrawingPen pen = graphics.DrawingFactory.CreatePen(Color.Blue, 20.0f / scale))
{
graphics.DrawRectangle(pen, new RectangleF(0, 0, image.Width, image.Height));
}
}
}
/// <summary>
/// Creates the image.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="pageInfo">The page information.</param>
/// <returns>A new instace of <see cref="VintasoftImage"/> class.</returns>
private Vintasoft.Imaging.VintasoftImage CreateImage(int width, int height, int scale, RasterGridPageMetadata pageInfo)
{
Vintasoft.Imaging.PixelFormat pixelFormat;
if (pageInfo.BitsPerPixel == 24)
pixelFormat = Vintasoft.Imaging.PixelFormat.Bgr24;
else if (pageInfo.BitsPerPixel == 32)
pixelFormat = Vintasoft.Imaging.PixelFormat.Bgra32;
else
throw new NotImplementedException();
return new Vintasoft.Imaging.VintasoftImage((int)Math.Round(width / (float)scale), (int)Math.Round(height / (float)scale), pixelFormat);
}
#endregion
#endregion
}
/// <summary>
/// Provides information about ratser page metadata and raster grid.
/// </summary>
public class RasterGridPageMetadata : Vintasoft.Imaging.Metadata.PageMetadata
{
#region Constructors
/// <summary>
/// Prevents a default instance of the <see cref="RasterGridPageMetadata"/> class from being created.
/// </summary>
private RasterGridPageMetadata()
: base("RasterGridPageExample")
{
}
#endregion
#region Properties
string _pageName = null;
/// <summary>
/// Gets the name of the page.
/// </summary>
public string PageName
{
get
{
return _pageName;
}
}
int _imageWidth = 0;
/// <summary>
/// Gets the width of the image, in pixels.
/// </summary>
public override int ImageWidth
{
get
{
return _imageWidth;
}
}
int _imageHeight = 0;
/// <summary>
/// Gets the height of the image, in pixels.
/// </summary>
public override int ImageHeight
{
get
{
return _imageHeight;
}
}
/// <summary>
/// Gets the bits per-pixel of the image.
/// </summary>
/// <value>
/// The bits per pixel.
/// </value>
public override int BitsPerPixel
{
get
{
return 24;
}
}
int _tileWidth = 0;
/// <summary>
/// Gets the width of the tile, in pixels, without scale.
/// </summary>
public int TileWidth
{
get
{
return _tileWidth;
}
}
int _tileHeight = 0;
/// <summary>
/// Gets the height of the tile, in pixels, without scale.
/// </summary>
public int TileHeight
{
get
{
return _tileHeight;
}
}
int[] _tileScales;
/// <summary>
/// Gets the supported tile scales.
/// </summary>
public int[] TileScales
{
get
{
return _tileScales;
}
}
/// <summary>
/// Gets a value indicating whether the information about image resolution is stored
/// in an image page.
/// </summary>
public override bool HasResolution
{
get
{
return true;
}
}
bool _canReadImageRegion = false;
/// <summary>
/// Gets a value that indicates that decoder can read a region of the image.
/// </summary>
public bool CanReadImageRegion
{
get
{
return _canReadImageRegion;
}
}
#endregion
#region Methods
/// <summary>
/// Parses page info uses specified reader.
/// </summary>
/// <param name="reader">The reader.</param>
/// <returns>A new instance of <see cref="RasterGridPageMetadata"/> class.</returns>
internal static RasterGridPageMetadata Parse(TextReader reader)
{
RasterGridPageMetadata result = new RasterGridPageMetadata();
result._pageName = ReadLine(reader);
result._imageWidth = ReadInt(reader);
result._imageHeight = ReadInt(reader);
result.Resolution = new Vintasoft.Imaging.Resolution(ReadInt(reader), ReadInt(reader));
result._tileWidth = ReadInt(reader);
result._tileHeight = ReadInt(reader);
string[] scaleStrings = ReadLine(reader).Split(',');
int[] scales = new int[scaleStrings.Length];
for (int i = 0; i < scales.Length; i++)
{
scales[i] = int.Parse(scaleStrings[i].Trim());
}
result._tileScales = scales;
result._canReadImageRegion = ReadLine(reader).ToLowerInvariant() == "true";
return result;
}
/// <summary>
/// Reads the string value from text reader.
/// </summary>
/// <param name="reader">The reader.</param>
/// <returns>The line.</returns>
private static string ReadLine(TextReader reader)
{
string result = reader.ReadLine();
while (result == "" || result.StartsWith("'"))
result = reader.ReadLine();
return result;
}
/// <summary>
/// Reads the int value from text reader.
/// </summary>
/// <param name="reader">The reader.</param>
/// <returns>The int value.</returns>
private static int ReadInt(TextReader reader)
{
return int.Parse(ReadLine(reader));
}
#endregion
}
''' <summary>
''' Provides the image decoder for IRasterGridDecoder example.
''' </summary>
Public Class RasterGridDecoderExample
Inherits Vintasoft.Imaging.Codecs.Decoders.DecoderBase
Implements Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder
#Region "Constants"
''' <summary>
''' The rect decoding time, in milliseconds (emulate image decoding).
''' </summary>
Private Const RectDecodingTimeMs As Integer = 1
#End Region
#Region "Fields"
''' <summary>
''' The list with information about pages.
''' </summary>
Private _pageInfos As New List(Of RasterGridPageMetadata)()
#End Region
#Region "Constructors"
''' <summary>
''' Initializes a new instance of the <see cref="RasterGridDecoderExample"/> class.
''' </summary>
''' <remarks>
''' This constructor is used in <see cref="T:Vintasoft.Imaging.Codecs.Decoders.AvailableDecoders" /> and
''' should not be used in real applications.
''' </remarks>
Public Sub New()
End Sub
''' <summary>
''' Initializes a new instance of the <see cref="RasterGridDecoderExample"/> class.
''' </summary>
''' <param name="stream">The stream, which stores raw data of image/document source.</param>
Public Sub New(stream As Stream)
MyBase.New(stream)
If Not IsValidFormat(stream) Then
Throw New NotSupportedException()
End If
Dim reader As New StreamReader(stream)
While Not reader.EndOfStream
_pageInfos.Add(RasterGridPageMetadata.Parse(reader))
End While
End Sub
#End Region
#Region "Properties"
''' <summary>
''' Gets the name of the decoder.
''' </summary>
Public Overrides ReadOnly Property Name() As String Implements Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder.Name
Get
Return RasterGridCodecExample.CodecName
End Get
End Property
#End Region
#Region "Methods"
#Region "PUBLIC"
''' <summary>
''' Determines that decoder can read a region of the image.
''' </summary>
''' <param name="scale">The rect scale.</param>
''' <param name="pageIndex">The zero based page index.</param>
''' <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
''' <returns>
''' <b>True</b> if decoder can read a region of the image;<br /><b>false</b> if decoder can read only rectangle of the image.
''' </returns>
''' <remarks>
''' <i>Region</i> represents a rectangular region on the image and
''' composed from a sequence of rectangles.
''' </remarks>
Public Function CanReadImageRegion(pageIndex As Integer, scale As Integer, decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings) As Boolean Implements Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder.CanReadImageRegion
Return _pageInfos(pageIndex).CanReadImageRegion
End Function
''' <summary>
''' Determines that decoder can progressively read the image.
''' </summary>
''' <param name="pageIndex">The zero based page index.</param>
''' <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
''' <returns>
''' <b>True</b> if decoder can progressively read the image;<br /><b>false</b> if decoder cannot progressively read the image.
''' </returns>
Public Function CanUseProgressiveDecoding(pageIndex As Integer, decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings) As Boolean Implements Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder.CanUseProgressiveDecoding
Return False
End Function
''' <summary>
''' Returns an image, which is associated with the specified page of image/document source.
''' </summary>
''' <param name="pageIndex">The zero-based page index in image/document source.</param>
''' <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
''' <param name="renderingSettings">Rendering settings used for rendering the image of page.
''' This parameter has effect only if <see cref="P:Vintasoft.Imaging.Codecs.Decoders.DecoderBase.IsVectorDecoder" /> property is equal to <b>True</b>.</param>
''' <param name="progressDelegate">Progress delegate.</param>
''' <returns>
''' Rendered image, which is associated with the specified page of image/document source, if decoder supports rendering;
''' otherwise, image associated with the specified page of the image source.
''' </returns>
Public Overrides Function GetImage(pageIndex As Integer, decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings, renderingSettings As Vintasoft.Imaging.Codecs.Decoders.RenderingSettings, progressDelegate As EventHandler(Of Vintasoft.Imaging.ProgressEventArgs)) As Vintasoft.Imaging.VintasoftImage
Throw New NotSupportedException()
End Function
''' <summary>
''' Returns information about image without loading the image data into memory.
''' </summary>
''' <param name="pageIndex">The zero-based page index in image/document source.</param>
''' <param name="renderingSettings">Rendering settings used for getting info about the image of page.
''' This parameter has effect only if <see cref="P:Vintasoft.Imaging.Codecs.Decoders.DecoderBase.IsVectorDecoder" /> property is equal to <b>True</b>.</param>
''' <param name="decodingSettings">decoding settings used for getting info about the image of page.</param>
''' <returns>
''' Information about the image associated with the page of the source image.
''' </returns>
Public Overrides Function GetImageInfo(pageIndex As Integer, renderingSettings As Vintasoft.Imaging.Codecs.Decoders.RenderingSettings, decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings) As Vintasoft.Imaging.Codecs.Decoders.ImageInfo
Dim pageInfo As RasterGridPageMetadata = _pageInfos(pageIndex)
Return New Vintasoft.Imaging.Codecs.Decoders.ImageInfo(pageInfo.ImageWidth, pageInfo.ImageHeight, pageInfo.BitsPerPixel, New Vintasoft.Imaging.Palette(), pageInfo.Resolution)
End Function
''' <summary>
''' Returns a scaled rectangle of raster image.
''' </summary>
''' <param name="pageIndex">The zero based page index.</param>
''' <param name="rectIndex">The zero based the rectangle index.</param>
''' <param name="scale">Scale factor. Possible values: 1 - original image rect should
''' be get; N - reduced image rect should be get.</param>
''' <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
''' <param name="imageLoadingProgress">Delegate of the image loading progress.
''' Can be set to <b>null</b> (<b>Nothing</b> in Visual Basic).</param>
''' <param name="intermediateImageRequest">Delegate for requesting intermediate image.
''' Can be set to <b>null</b> (<b>Nothing</b> in Visual Basic)</param>
''' <returns>
''' Scaled rectangle of image.
''' </returns>
Public Function GetImageRect(pageIndex As Integer, rectIndex As Integer, scale As Integer, decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings, imageLoadingProgress As EventHandler(Of Vintasoft.Imaging.ProgressEventArgs), intermediateImageRequest As EventHandler(Of Vintasoft.Imaging.ImageRendering.IntermediateImageRequestEventArgs)) As Vintasoft.Imaging.VintasoftImage Implements Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder.GetImageRect
Dim pageInfo As RasterGridPageMetadata = _pageInfos(pageIndex)
Dim grid As Rectangle() = GetImageRectGrid(pageIndex, decodingSettings)
Dim rect As Rectangle = grid(rectIndex)
Dim image As Vintasoft.Imaging.VintasoftImage = CreateImage(rect.Width, rect.Height, scale, pageInfo)
DrawTileInfo(image, "{rectIndex}" & vbLf & "1/{scale}", scale)
' emulate image decoding
If RectDecodingTimeMs > 0 Then
System.Threading.Thread.Sleep(RectDecodingTimeMs)
End If
Return image
End Function
''' <summary>
''' Returns a scaled region of raster image.
''' </summary>
''' <param name="pageIndex">The zero based page index.</param>
''' <param name="leftTopRectIndex">The zero based index of left-top rectangle.</param>
''' <param name="rightBottomRectIndex">The zero based index of right-bottom rectangle.</param>
''' <param name="scale">Scale factor. Possible values: 1 - original image rect should
''' be get; N - reduced image rect should be get.</param>
''' <param name="decodingSettings">Decoding settings.</param>
''' <param name="imageLoadingProgress">Delegate of the image loading progress.
''' Can be set to <b>null</b> (<b>Nothing</b> in Visual Basic).</param>
''' <param name="intermediateImageRequest">Delegate for requesting intermediate image.
''' Can be set to <b>null</b> (<b>Nothing</b> in Visual Basic)</param>
''' <returns>
''' Scaled region of image.
''' </returns>
Public Function GetImageRegion(pageIndex As Integer, leftTopRectIndex As Integer, rightBottomRectIndex As Integer, scale As Integer, decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings, imageLoadingProgress As EventHandler(Of Vintasoft.Imaging.ProgressEventArgs), _
intermediateImageRequest As EventHandler(Of Vintasoft.Imaging.ImageRendering.IntermediateImageRequestEventArgs)) As Vintasoft.Imaging.VintasoftImage Implements Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder.GetImageRegion
Dim pageInfo As RasterGridPageMetadata = _pageInfos(pageIndex)
Dim grid As Rectangle() = GetImageRectGrid(pageIndex, decodingSettings)
Dim leftTopRect As Rectangle = grid(leftTopRectIndex)
Dim rightBottomRect As Rectangle = grid(rightBottomRectIndex)
Dim rect As New Rectangle(leftTopRect.X, leftTopRect.Y, rightBottomRect.X + rightBottomRect.Width - leftTopRect.X, rightBottomRect.Y + rightBottomRect.Height - leftTopRect.Y)
Dim image As Vintasoft.Imaging.VintasoftImage = CreateImage(rect.Width, rect.Height, scale, pageInfo)
DrawTileInfo(image, "{leftTopRectIndex}:{rightBottomRectIndex}" & vbLf & "1/{scale}", scale)
' emulate image decoding
If RectDecodingTimeMs > 0 Then
System.Threading.Thread.Sleep(RectDecodingTimeMs)
End If
Return image
End Function
''' <summary>
''' Returns an image grid as array of rectangles.
''' </summary>
''' <param name="pageIndex">The zero based page index.</param>
''' <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
''' <returns>
''' An image grid as array of rectangles.
''' </returns>
''' <remarks>
''' Method must return an array with one rectangle which size is equal to the size
''' of image if decoder cannot get image by parts.
''' </remarks>
Public Function GetImageRectGrid(pageIndex As Integer, decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings) As Rectangle() Implements Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder.GetImageRectGrid
Dim pageInfo As RasterGridPageMetadata = _pageInfos(pageIndex)
Return SplitIntoTileRectangles(New Size(pageInfo.ImageWidth, pageInfo.ImageHeight), New Size(pageInfo.TileWidth, pageInfo.TileHeight))
End Function
''' <summary>
''' Returns an array of scale factors for rectangles of image grid.
''' </summary>
''' <param name="pageIndex">The zero based page index.</param>
''' <param name="decodingSettings">The decoding settings that should be used for decoding of page image.</param>
''' <returns>
''' An array of scale factors for rectangles of image grid.
''' </returns>
''' <remarks>
''' Possible values of scale factor:
''' <ul><li>1 - decoder can return image rectangle without scaling</li><li>N - decoder can return an image rectangle reduced N times</li></ul>
''' </remarks>
Public Function GetImageRectScales(pageIndex As Integer, decodingSettings As Vintasoft.Imaging.Codecs.Decoders.DecodingSettings) As Integer() Implements Vintasoft.Imaging.Codecs.Decoders.IRasterGridDecoder.GetImageRectScales
Return _pageInfos(pageIndex).TileScales
End Function
''' <summary>
''' Returns a metadata of specified page of image/document source.
''' </summary>
''' <param name="pageIndex">The zero-based page index in image/document source.</param>
''' <returns>
''' A metadata of specified page of image/document source.
''' </returns>
Public Overrides Function GetPageMetadata(pageIndex As Integer) As Vintasoft.Imaging.Metadata.PageMetadata
Return _pageInfos(pageIndex)
End Function
''' <summary>
''' Determines that stream contains image file in format of this decoder.
''' </summary>
''' <param name="stream">Stream with binary data of the image file.</param>
''' <returns>
''' <b>True</b> if stream contains image file in format of this decoder; otherwise, <b>false</b>.
''' </returns>
Public Overrides Function IsValidFormat(stream As Stream) As Boolean
Dim name__1 As String = Name
Dim index As Integer = 0
While stream.ReadByte() <> CByte(AscW(name__1(0)))
If System.Math.Max(System.Threading.Interlocked.Increment(index),index - 1) > 5 Then
Return False
End If
End While
stream.Position -= 1
Dim bytes As Byte() = New Byte(name__1.Length - 1) {}
stream.Read(bytes, 0, bytes.Length)
For i As Integer = 0 To bytes.Length - 1
If bytes(i) <> CByte(AscW(name__1(i))) Then
Return False
End If
Next
Return True
End Function
#End Region
#Region "PROTECTED"
''' <summary>
''' Returns the number of pages in the source file stream.
''' </summary>
''' <returns>
''' The number of pages in the source file stream.
''' </returns>
Protected Overrides Function GetPageCount() As Integer
Return _pageInfos.Count
End Function
#End Region
#Region "PRIVATE"
''' <summary>
''' Splits an image area into tile rectangles.
''' </summary>
''' <param name="imageSize">Size of the image.</param>
''' <param name="tileSize">Size of the tile.</param>
''' <returns>
''' An image grid as array of rectangles.
''' </returns>
Private Shared Function SplitIntoTileRectangles(imageSize As Size, tileSize As Size) As Rectangle()
Dim rectangles As New List(Of Rectangle)()
Dim rows As Integer = CInt(Math.Truncate(Math.Ceiling(CDbl(imageSize.Height) / tileSize.Height)))
Dim cols As Integer = CInt(Math.Truncate(Math.Ceiling(CDbl(imageSize.Width) / tileSize.Width)))
For row As Integer = 0 To rows - 1
For col As Integer = 0 To cols - 1
Dim width As Integer = tileSize.Width
Dim height As Integer = tileSize.Height
If col = cols - 1 Then
width = imageSize.Width - col * tileSize.Width
End If
If row = rows - 1 Then
height = imageSize.Height - row * tileSize.Height
End If
rectangles.Add(New Rectangle(col * tileSize.Width, row * tileSize.Height, width, height))
Next
Next
Return rectangles.ToArray()
End Function
''' <summary>
''' Draws the tile information.
''' </summary>
''' <param name="image">The image.</param>
''' <param name="tileInfo">The tile information.</param>
''' <param name="scale">The scale.</param>
Private Sub DrawTileInfo(image As Vintasoft.Imaging.VintasoftImage, tileInfo As String, scale As Integer)
Using graphics As Vintasoft.Imaging.Drawing.DrawingEngine = image.CreateDrawingEngine()
graphics.Clear(Color.White)
Using font As Vintasoft.Imaging.Drawing.IDrawingFont = graphics.DrawingFactory.CreateDefaultFont(Math.Max(10, 180F / scale))
Using brush As Vintasoft.Imaging.Drawing.IDrawingBrush = graphics.DrawingFactory.CreateSolidBrush(Color.Black)
graphics.DrawText(tileInfo, font, brush, New RectangleF(0, 0, image.Width, image.Height), New Vintasoft.Imaging.Drawing.TextLayoutProperties(Vintasoft.Imaging.AnchorType.Center, True))
End Using
End Using
Using pen As Vintasoft.Imaging.Drawing.IDrawingPen = graphics.DrawingFactory.CreatePen(Color.Blue, 20F / scale)
graphics.DrawRectangle(pen, New RectangleF(0, 0, image.Width, image.Height))
End Using
End Using
End Sub
''' <summary>
''' Creates the image.
''' </summary>
''' <param name="width">The width.</param>
''' <param name="height">The height.</param>
''' <param name="pageInfo">The page information.</param>
''' <returns>A new instace of <see cref="VintasoftImage"/> class.</returns>
Private Function CreateImage(width As Integer, height As Integer, scale As Integer, pageInfo As RasterGridPageMetadata) As Vintasoft.Imaging.VintasoftImage
Dim pixelFormat As Vintasoft.Imaging.PixelFormat
If pageInfo.BitsPerPixel = 24 Then
pixelFormat = Vintasoft.Imaging.PixelFormat.Bgr24
ElseIf pageInfo.BitsPerPixel = 32 Then
pixelFormat = Vintasoft.Imaging.PixelFormat.Bgra32
Else
Throw New NotImplementedException()
End If
Return New Vintasoft.Imaging.VintasoftImage(CInt(Math.Truncate(Math.Round(width / CSng(scale)))), CInt(Math.Truncate(Math.Round(height / CSng(scale)))), pixelFormat)
End Function
#End Region
#End Region
End Class
''' <summary>
''' Provides information about ratser page metadata and raster grid.
''' </summary>
Public Class RasterGridPageMetadata
Inherits Vintasoft.Imaging.Metadata.PageMetadata
#Region "Constructors"
''' <summary>
''' Prevents a default instance of the <see cref="RasterGridPageMetadata"/> class from being created.
''' </summary>
Private Sub New()
MyBase.New("RasterGridPageExample")
End Sub
#End Region
#Region "Properties"
Private _pageName As String = Nothing
''' <summary>
''' Gets the name of the page.
''' </summary>
Public ReadOnly Property PageName() As String
Get
Return _pageName
End Get
End Property
Private _imageWidth As Integer = 0
''' <summary>
''' Gets the width of the image, in pixels.
''' </summary>
Public Overrides ReadOnly Property ImageWidth() As Integer
Get
Return _imageWidth
End Get
End Property
Private _imageHeight As Integer = 0
''' <summary>
''' Gets the height of the image, in pixels.
''' </summary>
Public Overrides ReadOnly Property ImageHeight() As Integer
Get
Return _imageHeight
End Get
End Property
''' <summary>
''' Gets the bits per-pixel of the image.
''' </summary>
''' <value>
''' The bits per pixel.
''' </value>
Public Overrides ReadOnly Property BitsPerPixel() As Integer
Get
Return 24
End Get
End Property
Private _tileWidth As Integer = 0
''' <summary>
''' Gets the width of the tile, in pixels, without scale.
''' </summary>
Public ReadOnly Property TileWidth() As Integer
Get
Return _tileWidth
End Get
End Property
Private _tileHeight As Integer = 0
''' <summary>
''' Gets the height of the tile, in pixels, without scale.
''' </summary>
Public ReadOnly Property TileHeight() As Integer
Get
Return _tileHeight
End Get
End Property
Private _tileScales As Integer()
''' <summary>
''' Gets the supported tile scales.
''' </summary>
Public ReadOnly Property TileScales() As Integer()
Get
Return _tileScales
End Get
End Property
''' <summary>
''' Gets a value indicating whether the information about image resolution is stored
''' in an image page.
''' </summary>
Public Overrides ReadOnly Property HasResolution() As Boolean
Get
Return True
End Get
End Property
Private _canReadImageRegion As Boolean = False
''' <summary>
''' Gets a value that indicates that decoder can read a region of the image.
''' </summary>
Public ReadOnly Property CanReadImageRegion() As Boolean
Get
Return _canReadImageRegion
End Get
End Property
#End Region
#Region "Methods"
''' <summary>
''' Parses page info uses specified reader.
''' </summary>
''' <param name="reader">The reader.</param>
''' <returns>A new instance of <see cref="RasterGridPageMetadata"/> class.</returns>
Friend Shared Function Parse(reader As TextReader) As RasterGridPageMetadata
Dim result As New RasterGridPageMetadata()
result._pageName = ReadLine(reader)
result._imageWidth = ReadInt(reader)
result._imageHeight = ReadInt(reader)
result.Resolution = New Vintasoft.Imaging.Resolution(ReadInt(reader), ReadInt(reader))
result._tileWidth = ReadInt(reader)
result._tileHeight = ReadInt(reader)
Dim scaleStrings As String() = ReadLine(reader).Split(","C)
Dim scales As Integer() = New Integer(scaleStrings.Length - 1) {}
For i As Integer = 0 To scales.Length - 1
scales(i) = Integer.Parse(scaleStrings(i).Trim())
Next
result._tileScales = scales
result._canReadImageRegion = ReadLine(reader).ToLowerInvariant() = "true"
Return result
End Function
''' <summary>
''' Reads the string value from text reader.
''' </summary>
''' <param name="reader">The reader.</param>
''' <returns>The line.</returns>
Private Shared Function ReadLine(reader As TextReader) As String
Dim result As String = reader.ReadLine()
While result = "" OrElse result.StartsWith("'")
result = reader.ReadLine()
End While
Return result
End Function
''' <summary>
''' Reads the int value from text reader.
''' </summary>
''' <param name="reader">The reader.</param>
''' <returns>The int value.</returns>
Private Shared Function ReadInt(reader As TextReader) As Integer
Return Integer.Parse(ReadLine(reader))
End Function
#End Region
End Class
/// <summary>
/// Provides the image codec for IRasterGridDecoder example.
/// </summary>
/// <seealso cref="Register()"/>
/// <seealso cref="EnableRendering(ImageViewerBase)"/>
public class RasterGridCodecExample : Vintasoft.Imaging.Codecs.Codec
{
#region Constants
/// <summary>
/// The codec name.
/// </summary>
public const string CodecName = "RasterGridDecoderExample";
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="RasterGridCodecExample"/> class.
/// </summary>
public RasterGridCodecExample()
: base(CodecName, ".rgce")
{
}
#endregion
#region Properties
/// <summary>
/// Gets a value indicating whether codec can create decoder.
/// </summary>
public override bool CanCreateDecoder
{
get
{
return true;
}
}
/// <summary>
/// Gets a value indicating whether codec can create encoder.
/// </summary>
public override bool CanCreateEncoder
{
get
{
return false;
}
}
#endregion
#region Methods
/// <summary>
/// Registers this codec in the SDK.
/// </summary>
public static void Register()
{
Vintasoft.Imaging.Codecs.AvailableCodecs.AddCodec(new RasterGridCodecExample());
}
/// <summary>
/// Enables the rendering of this codec is specified viewer.
/// </summary>
/// <param name="viewer">The viewer.</param>
public static void EnableRendering(Vintasoft.Imaging.UI.ImageViewerBase viewer)
{
viewer.RenderingRequirements.SetRequirement(CodecName, new Vintasoft.Imaging.ImageRendering.ImageSizeRenderingRequirement(0));
}
/// <summary>
/// Creates a new decoder instance for decoding specified stream.
/// </summary>
/// <param name="stream">A stream which should be opened using decoder.</param>
/// <param name="layoutSettings">A layout settings of document.</param>
/// <returns>
/// New decoder instance for specified stream.
/// </returns>
public override Vintasoft.Imaging.Codecs.Decoders.DecoderBase CreateDecoder(Stream stream, Vintasoft.Imaging.Codecs.Decoders.DocumentLayoutSettings layoutSettings)
{
return new RasterGridDecoderExample(stream);
}
/// <summary>
/// Creates a new decoder instance of the codec.
/// </summary>
/// <returns>
/// The new decoder instance of the codec.
/// </returns>
public override Vintasoft.Imaging.Codecs.Decoders.DecoderBase CreateDecoder()
{
return new RasterGridDecoderExample();
}
/// <summary>
/// Creates a new encoder instance of the codec.
/// </summary>
/// <returns>
/// The new encoder instance of the codec.
/// </returns>
/// <exception cref="System.NotSupportedException"></exception>
public override Vintasoft.Imaging.Codecs.Encoders.EncoderBase CreateEncoder()
{
throw new NotSupportedException();
}
#endregion
}
''' <summary>
''' Provides the image codec for IRasterGridDecoder example.
''' </summary>
''' <seealso cref="Register()"/>
''' <seealso cref="EnableRendering(ImageViewerBase)"/>
Public Class RasterGridCodecExample
Inherits Vintasoft.Imaging.Codecs.Codec
#Region "Constants"
''' <summary>
''' The codec name.
''' </summary>
Public Const CodecName As String = "RasterGridDecoderExample"
#End Region
#Region "Constructors"
''' <summary>
''' Initializes a new instance of the <see cref="RasterGridCodecExample"/> class.
''' </summary>
Public Sub New()
MyBase.New(CodecName, ".rgce")
End Sub
#End Region
#Region "Properties"
''' <summary>
''' Gets a value indicating whether codec can create decoder.
''' </summary>
Public Overrides ReadOnly Property CanCreateDecoder() As Boolean
Get
Return True
End Get
End Property
''' <summary>
''' Gets a value indicating whether codec can create encoder.
''' </summary>
Public Overrides ReadOnly Property CanCreateEncoder() As Boolean
Get
Return False
End Get
End Property
#End Region
#Region "Methods"
''' <summary>
''' Registers this codec in the SDK.
''' </summary>
Public Shared Sub Register()
Vintasoft.Imaging.Codecs.AvailableCodecs.AddCodec(New RasterGridCodecExample())
End Sub
''' <summary>
''' Enables the rendering of this codec is specified viewer.
''' </summary>
''' <param name="viewer">The viewer.</param>
Public Shared Sub EnableRendering(viewer As Vintasoft.Imaging.UI.ImageViewerBase)
viewer.RenderingRequirements.SetRequirement(CodecName, New Vintasoft.Imaging.ImageRendering.ImageSizeRenderingRequirement(0))
End Sub
''' <summary>
''' Creates a new decoder instance for decoding specified stream.
''' </summary>
''' <param name="stream">A stream which should be opened using decoder.</param>
''' <param name="layoutSettings">A layout settings of document.</param>
''' <returns>
''' New decoder instance for specified stream.
''' </returns>
Public Overrides Function CreateDecoder(stream As Stream, layoutSettings As Vintasoft.Imaging.Codecs.Decoders.DocumentLayoutSettings) As Vintasoft.Imaging.Codecs.Decoders.DecoderBase
Return New RasterGridDecoderExample(stream)
End Function
''' <summary>
''' Creates a new decoder instance of the codec.
''' </summary>
''' <returns>
''' The new decoder instance of the codec.
''' </returns>
Public Overrides Function CreateDecoder() As Vintasoft.Imaging.Codecs.Decoders.DecoderBase
Return New RasterGridDecoderExample()
End Function
''' <summary>
''' Creates a new encoder instance of the codec.
''' </summary>
''' <returns>
''' The new encoder instance of the codec.
''' </returns>
''' <exception cref="System.NotSupportedException"></exception>
Public Overrides Function CreateEncoder() As Vintasoft.Imaging.Codecs.Encoders.EncoderBase
Throw New NotSupportedException()
End Function
#End Region
End Class
using System;
using System.Windows.Forms;
using Vintasoft.Imaging.UI;
using DemosCommonCode;
namespace UserGuide.Codecs.RasterGridDecoder
{
public partial class RasterGridExampleForm : Form
{
static RasterGridExampleForm()
{
// register the RasterGridCodecExample codec in the SDK
RasterGridCodecExample.Register();
}
public RasterGridExampleForm()
{
InitializeComponent();
// specify that image viewer must use 128MB cache
imageViewer1.RendererCacheSize = 128;
// specify that RasterGridCodecExample class must render images in thumbnail viewer
RasterGridCodecExample.EnableRendering(thumbnailViewer1);
// specify that RasterGridCodecExample class must render images in image viewer
RasterGridCodecExample.EnableRendering(imageViewer1);
}
private void openButton_Click(object sender, EventArgs e)
{
// open RasterGridSource.rgce file using OpenFileDialog
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
// add images to the viewers
imageViewer1.Images.Add(openFileDialog1.FileName);
}
}
}
}
Imports System.Windows.Forms
Imports Vintasoft.Imaging.UI
Imports DemosCommonCode
Namespace UserGuide.Codecs.RasterGridDecoder
Public Partial Class RasterGridExampleForm
Inherits Form
Shared Sub New()
' register the RasterGridCodecExample codec in the SDK
RasterGridCodecExample.Register()
End Sub
Public Sub New()
InitializeComponent()
' specify that image viewer must use 128MB cache
imageViewer1.RendererCacheSize = 128
' specify that RasterGridCodecExample class must render images in thumbnail viewer
RasterGridCodecExample.EnableRendering(thumbnailViewer1)
' specify that RasterGridCodecExample class must render images in image viewer
RasterGridCodecExample.EnableRendering(imageViewer1)
End Sub
Private Sub openButton_Click(sender As Object, e As EventArgs)
' open RasterGridSource.rgce file using OpenFileDialog
If openFileDialog1.ShowDialog() = DialogResult.OK Then
' add images to the viewers
imageViewer1.Images.Add(openFileDialog1.FileName)
End If
End Sub
End Class
End Namespace