IRasterGridDecoder interface that supports large images"/>
/// <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