Update: Document Importing & QR Detection
This commit is contained in:
@@ -58,7 +58,13 @@ namespace Disco.BI.DocumentTemplateBI
|
|||||||
foreach (var pdfFieldPosition in pdfReader.AcroFields.GetFieldPositions("DiscoAttachmentId"))
|
foreach (var pdfFieldPosition in pdfReader.AcroFields.GetFieldPositions("DiscoAttachmentId"))
|
||||||
{
|
{
|
||||||
var pdfPageSize = pdfReader.GetPageSize(pdfFieldPosition.page);
|
var pdfPageSize = pdfReader.GetPageSize(pdfFieldPosition.page);
|
||||||
locations.Add(new RectangleF((float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Left / pdfPageSize.Width) - 0.1)), (float)System.Math.Min(1.0, System.Math.Max(0.0, (double)((pdfPageSize.Height - pdfFieldPosition.position.Top) / pdfPageSize.Height) - 0.1)), (float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Width / pdfPageSize.Width) + 0.2)), (float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Height / pdfPageSize.Height) + 0.2))));
|
// Original Position
|
||||||
|
locations.Add(new RectangleF(
|
||||||
|
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Left / pdfPageSize.Width) - 0.05)),
|
||||||
|
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)((pdfPageSize.Height - pdfFieldPosition.position.Top) / pdfPageSize.Height) - 0.05)),
|
||||||
|
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Width / pdfPageSize.Width) + 0.1)),
|
||||||
|
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(pdfFieldPosition.position.Height / pdfPageSize.Height) + 0.1))
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pdfReader.Close();
|
pdfReader.Close();
|
||||||
|
|||||||
@@ -124,6 +124,54 @@ namespace Disco.BI.Extensions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Image Extensions
|
#region Image Extensions
|
||||||
|
|
||||||
|
public static Bitmap RotateImage(this Image Source, float Angle, Brush BackgroundColor = null, bool ResizeIfOver45Deg = true)
|
||||||
|
{
|
||||||
|
int destWidth = Source.Width;
|
||||||
|
int destHeight = Source.Height;
|
||||||
|
bool resizedDest = false;
|
||||||
|
|
||||||
|
if (ResizeIfOver45Deg && ((Angle > 45 && Angle < 135) || (Angle < -45 && Angle > -135)))
|
||||||
|
{
|
||||||
|
destWidth = Source.Height;
|
||||||
|
destHeight = Source.Width;
|
||||||
|
resizedDest = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap destination = new Bitmap(destWidth, destHeight);
|
||||||
|
destination.SetResolution(Source.HorizontalResolution, Source.VerticalResolution);
|
||||||
|
|
||||||
|
using (Graphics destinationGraphics = Graphics.FromImage(destination))
|
||||||
|
{
|
||||||
|
destinationGraphics.CompositingQuality = CompositingQuality.HighQuality;
|
||||||
|
destinationGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||||
|
destinationGraphics.SmoothingMode = SmoothingMode.HighQuality;
|
||||||
|
|
||||||
|
if (BackgroundColor != null)
|
||||||
|
destinationGraphics.FillRectangle(BackgroundColor, destinationGraphics.VisibleClipBounds);
|
||||||
|
|
||||||
|
float offsetWidth = destWidth / 2;
|
||||||
|
float offsetHeight = destHeight / 2;
|
||||||
|
|
||||||
|
destinationGraphics.TranslateTransform(offsetWidth, offsetHeight);
|
||||||
|
destinationGraphics.RotateTransform(Angle);
|
||||||
|
|
||||||
|
RectangleF destinationLocation;
|
||||||
|
|
||||||
|
if (resizedDest)
|
||||||
|
destinationLocation = new RectangleF(
|
||||||
|
offsetHeight * -1, offsetWidth * -1,
|
||||||
|
destHeight, destWidth);
|
||||||
|
else
|
||||||
|
destinationLocation = new RectangleF(
|
||||||
|
offsetWidth * -1, offsetHeight * -1,
|
||||||
|
destWidth, destHeight);
|
||||||
|
|
||||||
|
destinationGraphics.DrawImage(Source, destinationLocation, new RectangleF(0, 0, Source.Width, Source.Height), GraphicsUnit.Pixel);
|
||||||
|
}
|
||||||
|
return destination;
|
||||||
|
}
|
||||||
|
|
||||||
public static Bitmap ResizeImage(this Image Source, int Width, int Height, Brush BackgroundColor = null)
|
public static Bitmap ResizeImage(this Image Source, int Width, int Height, Brush BackgroundColor = null)
|
||||||
{
|
{
|
||||||
Bitmap destination = new Bitmap(Width, Height);
|
Bitmap destination = new Bitmap(Width, Height);
|
||||||
|
|||||||
@@ -17,11 +17,31 @@ using Disco.Models.Repository;
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using com.google.zxing.common;
|
using com.google.zxing.common;
|
||||||
using BitMiracle.LibTiff.Classic;
|
using BitMiracle.LibTiff.Classic;
|
||||||
|
using System.Drawing.Imaging;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Disco.BI.Interop.Pdf
|
namespace Disco.BI.Interop.Pdf
|
||||||
{
|
{
|
||||||
public static class PdfImporter
|
public static class PdfImporter
|
||||||
{
|
{
|
||||||
|
public static RectangleF CalculateLocationRatio(this Result zxingResult, int ImageWidth, int ImageHeight)
|
||||||
|
{
|
||||||
|
var orderedPoints = zxingResult.ResultPoints.OrderBy(p => p.X * p.Y).ToArray();
|
||||||
|
var topLeftPoint = orderedPoints.First();
|
||||||
|
var bottomRightPoint = orderedPoints.Last();
|
||||||
|
|
||||||
|
var x = topLeftPoint.X;
|
||||||
|
var y = topLeftPoint.Y;
|
||||||
|
var width = bottomRightPoint.X - x;
|
||||||
|
var height = bottomRightPoint.Y - y;
|
||||||
|
|
||||||
|
return new RectangleF(
|
||||||
|
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(x / ImageWidth) - 0.05)),
|
||||||
|
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(y / ImageHeight) - 0.05)),
|
||||||
|
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(width / ImageWidth) + 0.1)),
|
||||||
|
(float)System.Math.Min(1.0, System.Math.Max(0.0, (double)(height / ImageHeight) + 0.1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private class DetectImageResult : IDisposable
|
private class DetectImageResult : IDisposable
|
||||||
{
|
{
|
||||||
@@ -29,12 +49,46 @@ namespace Disco.BI.Interop.Pdf
|
|||||||
public Point ResultOffset { get; set; }
|
public Point ResultOffset { get; set; }
|
||||||
public double ResultScale { get; set; }
|
public double ResultScale { get; set; }
|
||||||
|
|
||||||
|
public float CalculateRotation()
|
||||||
|
{
|
||||||
|
var p1 = this.Result.ResultPoints[0];
|
||||||
|
var p2 = this.Result.ResultPoints[1];
|
||||||
|
double rotOpposite = p1.X - p2.X;
|
||||||
|
double rotAdjacent = p1.Y - p2.Y;
|
||||||
|
float rotation = 0;
|
||||||
|
|
||||||
|
if (rotOpposite != 0 || rotAdjacent != 0)
|
||||||
|
{
|
||||||
|
rotation = (float)(Math.Atan2(rotOpposite, rotAdjacent) * (180 / Math.PI)); // Degrees
|
||||||
|
}
|
||||||
|
|
||||||
|
return rotation;
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
// Do Nothing; yet...
|
// Do Nothing; yet...
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class DetectStateHints
|
||||||
|
{
|
||||||
|
public List<Tuple<RectangleF, Rotation>> PriorDetections { get; set; }
|
||||||
|
|
||||||
|
public DetectStateHints()
|
||||||
|
{
|
||||||
|
this.PriorDetections = new List<Tuple<RectangleF, Rotation>>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum Rotation
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
Degrees90 = 1,
|
||||||
|
DegreesNeg90 = 2,
|
||||||
|
Degrees180 = 3
|
||||||
|
}
|
||||||
|
|
||||||
private class DetectPageResult : IDisposable
|
private class DetectPageResult : IDisposable
|
||||||
{
|
{
|
||||||
public int PageNumber { get; set; }
|
public int PageNumber { get; set; }
|
||||||
@@ -86,7 +140,72 @@ namespace Disco.BI.Interop.Pdf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DetectImageResult DetectImage(DiscoDataContext dbContext, Bitmap pageImageOriginal, string SessionId, IEnumerable<DocumentTemplate> detectDocumentTemplates)
|
private static Tuple<Result, Rectangle, Rotation> DetectImageFromSegment(Bitmap pageImage, QRCodeMultiReader zxingReader, Hashtable zxingReaderHints, RectangleF LocationPercentage, Rotation Rotation)
|
||||||
|
{
|
||||||
|
System.Drawing.Rectangle region;
|
||||||
|
|
||||||
|
switch (Rotation)
|
||||||
|
{
|
||||||
|
case Rotation.None: // Original Position
|
||||||
|
region = new Rectangle(
|
||||||
|
(int)(pageImage.Width * LocationPercentage.Left),
|
||||||
|
(int)(pageImage.Height * LocationPercentage.Top),
|
||||||
|
(int)(pageImage.Width * LocationPercentage.Width),
|
||||||
|
(int)(pageImage.Height * LocationPercentage.Height));
|
||||||
|
break;
|
||||||
|
case Rotation.Degrees90: // Clockwise 90 degrees
|
||||||
|
region = new Rectangle(
|
||||||
|
(int)(pageImage.Width - (pageImage.Width * (LocationPercentage.Top + LocationPercentage.Height))),
|
||||||
|
(int)(pageImage.Height * LocationPercentage.Left),
|
||||||
|
(int)(pageImage.Width * LocationPercentage.Height),
|
||||||
|
(int)(pageImage.Height * LocationPercentage.Width));
|
||||||
|
break;
|
||||||
|
case Rotation.DegreesNeg90: // Anti-clockwise 90 degrees
|
||||||
|
region = new Rectangle(
|
||||||
|
(int)(pageImage.Width * LocationPercentage.Top),
|
||||||
|
(int)(pageImage.Height - (pageImage.Height * (LocationPercentage.Left + LocationPercentage.Width))),
|
||||||
|
(int)(pageImage.Width * LocationPercentage.Height),
|
||||||
|
(int)(pageImage.Height * LocationPercentage.Width));
|
||||||
|
break;
|
||||||
|
case Rotation.Degrees180: // 180 degrees
|
||||||
|
region = new Rectangle(
|
||||||
|
(int)(pageImage.Width - (pageImage.Width * (LocationPercentage.Left + LocationPercentage.Width))),
|
||||||
|
(int)(pageImage.Height - (pageImage.Height * (LocationPercentage.Top + LocationPercentage.Height))),
|
||||||
|
(int)(pageImage.Width * LocationPercentage.Width),
|
||||||
|
(int)(pageImage.Height * LocationPercentage.Height));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new InvalidOperationException("Unknown Rotation");
|
||||||
|
}
|
||||||
|
|
||||||
|
LuminanceSource zxingSource;
|
||||||
|
using (Bitmap pageImageRegion = new Bitmap(region.Width, region.Height))
|
||||||
|
{
|
||||||
|
pageImageRegion.SetResolution(pageImage.HorizontalResolution, pageImage.VerticalResolution);
|
||||||
|
|
||||||
|
using (Graphics pageImageRegionGraphics = Graphics.FromImage(pageImageRegion))
|
||||||
|
{
|
||||||
|
pageImageRegionGraphics.DrawImage(pageImage, 0, 0, region, GraphicsUnit.Pixel);
|
||||||
|
}
|
||||||
|
|
||||||
|
zxingSource = new BitmapLuminanceSource(pageImageRegion);
|
||||||
|
}
|
||||||
|
var zxingHB = new HybridBinarizer(zxingSource);
|
||||||
|
var zxingBB = new BinaryBitmap(zxingHB);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var zxingResult = zxingReader.decode(zxingBB, zxingReaderHints);
|
||||||
|
if (zxingResult != null)
|
||||||
|
return new Tuple<Result, Rectangle, Rotation>(zxingResult, region, Rotation);
|
||||||
|
}
|
||||||
|
catch (ReaderException)
|
||||||
|
{
|
||||||
|
// Ignore Location Errors
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DetectImageResult DetectImage(DiscoDataContext dbContext, Bitmap pageImageOriginal, string SessionId, IEnumerable<DocumentTemplate> detectDocumentTemplates, DetectStateHints StateHints)
|
||||||
{
|
{
|
||||||
Bitmap pageImage = pageImageOriginal;
|
Bitmap pageImage = pageImageOriginal;
|
||||||
double pageImageModifiedScale = 1;
|
double pageImageModifiedScale = 1;
|
||||||
@@ -99,69 +218,77 @@ namespace Disco.BI.Interop.Pdf
|
|||||||
pageImageModifiedScale = pageImage.HorizontalResolution / 72;
|
pageImageModifiedScale = pageImage.HorizontalResolution / 72;
|
||||||
int newWidth = (int)((72 / pageImage.HorizontalResolution) * pageImage.Width);
|
int newWidth = (int)((72 / pageImage.HorizontalResolution) * pageImage.Width);
|
||||||
int newHeight = (int)((72 / pageImage.VerticalResolution) * pageImage.Height);
|
int newHeight = (int)((72 / pageImage.VerticalResolution) * pageImage.Height);
|
||||||
|
|
||||||
pageImage = pageImage.ResizeImage(newWidth, newHeight);
|
pageImage = pageImage.ResizeImage(newWidth, newHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result zxingResult = default(Result);
|
Tuple<Result, Rectangle, Rotation> result = default(Tuple<Result, Rectangle, Rotation>);
|
||||||
Point zxingResultOffset = Point.Empty;
|
|
||||||
QRCodeMultiReader zxingMfr = new QRCodeMultiReader();
|
QRCodeMultiReader zxingMfr = new QRCodeMultiReader();
|
||||||
Hashtable zxingMfrHints = new Hashtable();
|
Hashtable zxingMfrHints = new Hashtable();
|
||||||
zxingMfrHints.Add(DecodeHintType.TRY_HARDER, true);
|
zxingMfrHints.Add(DecodeHintType.TRY_HARDER, true);
|
||||||
// Look in 'Known' locations
|
|
||||||
foreach (DocumentTemplate dt in detectDocumentTemplates)
|
|
||||||
|
// Look in previously found locations
|
||||||
|
if (StateHints.PriorDetections.Count > 0)
|
||||||
{
|
{
|
||||||
var locationBag = dt.QRCodeLocations(dbContext);
|
foreach (var previousLocation in StateHints.PriorDetections)
|
||||||
foreach (var location in locationBag)
|
|
||||||
{
|
{
|
||||||
System.Drawing.Rectangle region = new Rectangle(
|
result = DetectImageFromSegment(pageImage, zxingMfr, zxingMfrHints,
|
||||||
(int)(pageImage.Width * location.Left),
|
previousLocation.Item1, previousLocation.Item2);
|
||||||
(int)(pageImage.Width * location.Top),
|
if (result != null)
|
||||||
(int)(pageImage.Width * location.Width),
|
|
||||||
(int)(pageImage.Height * location.Height));
|
|
||||||
RGBLuminanceSource zxingSource;
|
|
||||||
using (Bitmap pageImageRegion = new Bitmap(region.Width, region.Height))
|
|
||||||
{
|
|
||||||
using (Graphics pageImageRegionGraphics = Graphics.FromImage(pageImageRegion))
|
|
||||||
{
|
|
||||||
pageImageRegionGraphics.DrawImage(pageImage, 0, 0, region, GraphicsUnit.Pixel);
|
|
||||||
}
|
|
||||||
zxingSource = new RGBLuminanceSource(pageImageRegion, region.Width, region.Height);
|
|
||||||
}
|
|
||||||
var zxingHB = new HybridBinarizer(zxingSource);
|
|
||||||
var zxingBB = new BinaryBitmap(zxingHB);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
zxingResult = zxingMfr.decode(zxingBB, zxingMfrHints);
|
|
||||||
zxingResultOffset = region.Location;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
catch (ReaderException)
|
|
||||||
{
|
|
||||||
// Ignore Location Errors
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (zxingResult != null)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (zxingResult == null)
|
if (result == null)
|
||||||
{
|
{
|
||||||
// Not found with 'known' locations
|
// Try the whole image
|
||||||
// Try whole image
|
var zxingSource = new BitmapLuminanceSource(pageImage);
|
||||||
var zxingSource = new RGBLuminanceSource(pageImage, pageImage.Width, pageImage.Height);
|
|
||||||
var zxingHB = new HybridBinarizer(zxingSource);
|
var zxingHB = new HybridBinarizer(zxingSource);
|
||||||
var zxingBB = new BinaryBitmap(zxingHB);
|
var zxingBB = new BinaryBitmap(zxingHB);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
zxingResult = zxingMfr.decode(zxingBB, zxingMfrHints);
|
var zxingResult = zxingMfr.decode(zxingBB, zxingMfrHints);
|
||||||
|
if (zxingResult != null)
|
||||||
|
{
|
||||||
|
result = new Tuple<Result, Rectangle, Rotation>(zxingResult, new Rectangle(0, 0, pageImage.Width, pageImage.Height), Rotation.None);
|
||||||
|
|
||||||
|
StateHints.PriorDetections.Insert(0, new Tuple<RectangleF, Rotation>(
|
||||||
|
result.Item1.CalculateLocationRatio(pageImage.Width, pageImage.Height)
|
||||||
|
, Rotation.None));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (ReaderException)
|
catch (ReaderException)
|
||||||
{
|
{
|
||||||
// Ignore Errors
|
// Ignore Errors
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
// Look in 'Known' locations
|
||||||
|
for (int rotationIndex = 0; rotationIndex < 4; rotationIndex++)
|
||||||
|
{
|
||||||
|
foreach (DocumentTemplate dt in detectDocumentTemplates)
|
||||||
|
{
|
||||||
|
var locationBag = dt.QRCodeLocations(dbContext);
|
||||||
|
foreach (var location in locationBag)
|
||||||
|
{
|
||||||
|
result = DetectImageFromSegment(pageImage, zxingMfr, zxingMfrHints,
|
||||||
|
location, (Rotation)rotationIndex);
|
||||||
|
|
||||||
if (zxingResult != null)
|
StateHints.PriorDetections.Insert(0, new Tuple<RectangleF, Rotation>(location, (Rotation)rotationIndex));
|
||||||
return new DetectImageResult() { Result = zxingResult, ResultOffset = zxingResultOffset, ResultScale = pageImageModifiedScale };
|
}
|
||||||
|
if (result != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (result != null)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != null)
|
||||||
|
|
||||||
|
return new DetectImageResult() { Result = result.Item1, ResultOffset = result.Item2.Location, ResultScale = pageImageModifiedScale };
|
||||||
else
|
else
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -176,7 +303,7 @@ namespace Disco.BI.Interop.Pdf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DetectPageResult DetectPage(DiscoDataContext dbContext, PdfReader pdfReader, int PageNumber, string SessionId, string DataStoreSessionCacheLocation, IEnumerable<DocumentTemplate> detectDocumentTemplates)
|
private static DetectPageResult DetectPage(DiscoDataContext dbContext, PdfReader pdfReader, int PageNumber, string SessionId, string DataStoreSessionCacheLocation, IEnumerable<DocumentTemplate> detectDocumentTemplates, DetectStateHints StateHints)
|
||||||
{
|
{
|
||||||
DetectPageResult result = new DetectPageResult() { PageNumber = PageNumber };
|
DetectPageResult result = new DetectPageResult() { PageNumber = PageNumber };
|
||||||
|
|
||||||
@@ -198,13 +325,23 @@ namespace Disco.BI.Interop.Pdf
|
|||||||
{
|
{
|
||||||
DocumentImporterLog.LogImportPageProgress(SessionId, PageNumber, (int)(10 + (pageProgressInterval * pageImages.IndexOf(pageImageOriginal))), String.Format("Processing Page Image {0} of {1}", pageImages.IndexOf(pageImageOriginal) + 1, pageImages.Count));
|
DocumentImporterLog.LogImportPageProgress(SessionId, PageNumber, (int)(10 + (pageProgressInterval * pageImages.IndexOf(pageImageOriginal))), String.Format("Processing Page Image {0} of {1}", pageImages.IndexOf(pageImageOriginal) + 1, pageImages.Count));
|
||||||
|
|
||||||
using (var zxingResult = DetectImage(dbContext, pageImageOriginal, SessionId, detectDocumentTemplates))
|
using (var zxingResult = DetectImage(dbContext, pageImageOriginal, SessionId, detectDocumentTemplates, StateHints))
|
||||||
{
|
{
|
||||||
if (zxingResult != null)
|
if (zxingResult != null)
|
||||||
{
|
{
|
||||||
if (DocumentUniqueIdentifier.IsDocumentUniqueIdentifier(zxingResult.Result.Text))
|
if (DocumentUniqueIdentifier.IsDocumentUniqueIdentifier(zxingResult.Result.Text))
|
||||||
{
|
{
|
||||||
|
float imageRotation = zxingResult.CalculateRotation();
|
||||||
|
|
||||||
result.DrawThumbnailImageResult(zxingResult, pageImageOriginal);
|
result.DrawThumbnailImageResult(zxingResult, pageImageOriginal);
|
||||||
|
|
||||||
|
if (imageRotation != 0)
|
||||||
|
{
|
||||||
|
var preImageRotation = result.ThumbnailImage.Montage;
|
||||||
|
result.ThumbnailImage.Montage = result.ThumbnailImage.Montage.RotateImage(imageRotation);
|
||||||
|
preImageRotation.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
result.ThumbnailImage.Montage.SavePng(pageThumbnailFilename);
|
result.ThumbnailImage.Montage.SavePng(pageThumbnailFilename);
|
||||||
DocumentImporterLog.LogImportPageImageUpdate(SessionId, PageNumber);
|
DocumentImporterLog.LogImportPageImageUpdate(SessionId, PageNumber);
|
||||||
|
|
||||||
@@ -213,6 +350,14 @@ namespace Disco.BI.Interop.Pdf
|
|||||||
{
|
{
|
||||||
using (Image mimeTypeIcon = Disco.Properties.Resources.MimeType_pdf16)
|
using (Image mimeTypeIcon = Disco.Properties.Resources.MimeType_pdf16)
|
||||||
attachmentThumbImage.Montage.EmbedIconOverlay(mimeTypeIcon);
|
attachmentThumbImage.Montage.EmbedIconOverlay(mimeTypeIcon);
|
||||||
|
|
||||||
|
if (imageRotation != 0)
|
||||||
|
{
|
||||||
|
var preImageRotation = attachmentThumbImage.Montage;
|
||||||
|
attachmentThumbImage.Montage = attachmentThumbImage.Montage.RotateImage(imageRotation, Brushes.White);
|
||||||
|
preImageRotation.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
attachmentThumbImage.Montage.SaveJpg(95, result.AttachmentThumbnailImage);
|
attachmentThumbImage.Montage.SaveJpg(95, result.AttachmentThumbnailImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,12 +394,14 @@ namespace Disco.BI.Interop.Pdf
|
|||||||
|
|
||||||
double progressInterval = 70 / pdfReader.NumberOfPages;
|
double progressInterval = 70 / pdfReader.NumberOfPages;
|
||||||
|
|
||||||
|
DetectStateHints detectStateHints = new DetectStateHints();
|
||||||
|
|
||||||
for (int PageNumber = 1; PageNumber <= pdfReader.NumberOfPages; PageNumber++)
|
for (int PageNumber = 1; PageNumber <= pdfReader.NumberOfPages; PageNumber++)
|
||||||
{
|
{
|
||||||
DocumentImporterLog.LogImportProgress(SessionId, (int)(PageNumber * progressInterval), string.Format("Processing Page {0} of {1}", PageNumber, pdfReader.NumberOfPages));
|
DocumentImporterLog.LogImportProgress(SessionId, (int)(PageNumber * progressInterval), string.Format("Processing Page {0} of {1}", PageNumber, pdfReader.NumberOfPages));
|
||||||
DocumentImporterLog.LogImportPageStarting(SessionId, PageNumber);
|
DocumentImporterLog.LogImportPageStarting(SessionId, PageNumber);
|
||||||
|
|
||||||
using (var pageResult = DetectPage(dbContext, pdfReader, PageNumber, SessionId, dataStoreSessionPagesCacheLocation, detectDocumentTemplates))
|
using (var pageResult = DetectPage(dbContext, pdfReader, PageNumber, SessionId, dataStoreSessionPagesCacheLocation, detectDocumentTemplates, detectStateHints))
|
||||||
{
|
{
|
||||||
if (pageResult.DetectedIdentifier != null)
|
if (pageResult.DetectedIdentifier != null)
|
||||||
{
|
{
|
||||||
@@ -468,4 +615,357 @@ namespace Disco.BI.Interop.Pdf
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2012 ZXing.Net authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/// <summary>
|
||||||
|
/// The base class for luminance sources which supports
|
||||||
|
/// cropping and rotating based upon the luminance values.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class BaseLuminanceSource : LuminanceSource
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
protected sbyte[] luminances;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BaseLuminanceSource"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="width">The width.</param>
|
||||||
|
/// <param name="height">The height.</param>
|
||||||
|
protected BaseLuminanceSource(int width, int height)
|
||||||
|
: base(width, height)
|
||||||
|
{
|
||||||
|
luminances = new sbyte[width * height];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BaseLuminanceSource"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="luminanceArray">The luminance array.</param>
|
||||||
|
/// <param name="width">The width.</param>
|
||||||
|
/// <param name="height">The height.</param>
|
||||||
|
protected BaseLuminanceSource(sbyte[] luminanceArray, int width, int height)
|
||||||
|
: base(width, height)
|
||||||
|
{
|
||||||
|
luminances = luminanceArray;
|
||||||
|
//Buffer.BlockCopy(luminanceArray, 0, luminances, 0, width * height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetches one row of luminance data from the underlying platform's bitmap. Values range from
|
||||||
|
/// 0 (black) to 255 (white). It is preferable for implementations of this method
|
||||||
|
/// to only fetch this row rather than the whole image, since no 2D Readers may be installed and
|
||||||
|
/// getMatrix() may never be called.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="y">The row to fetch, 0 <= y < Height.</param>
|
||||||
|
/// <param name="row">An optional preallocated array. If null or too small, it will be ignored.
|
||||||
|
/// Always use the returned object, and ignore the .length of the array.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// An array containing the luminance data.
|
||||||
|
/// </returns>
|
||||||
|
override public sbyte[] getRow(int y, sbyte[] row)
|
||||||
|
{
|
||||||
|
int width = Width;
|
||||||
|
if (row == null || row.Length < width)
|
||||||
|
{
|
||||||
|
row = new sbyte[width];
|
||||||
|
}
|
||||||
|
//for (int i = 0; i < width; i++)
|
||||||
|
// row[i] = luminances[y * width + i];
|
||||||
|
Buffer.BlockCopy(luminances, y * width, row, 0, width);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override sbyte[] Matrix
|
||||||
|
{
|
||||||
|
get { return luminances; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new object with rotated image data by 90 degrees counterclockwise.
|
||||||
|
/// Only callable if {@link #isRotateSupported()} is true.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A rotated version of this object.
|
||||||
|
/// </returns>
|
||||||
|
public override LuminanceSource rotateCounterClockwise()
|
||||||
|
{
|
||||||
|
var rotatedLuminances = new sbyte[Width * Height];
|
||||||
|
var newWidth = Height;
|
||||||
|
var newHeight = Width;
|
||||||
|
var localLuminances = Matrix;
|
||||||
|
for (var yold = 0; yold < Height; yold++)
|
||||||
|
{
|
||||||
|
for (var xold = 0; xold < Width; xold++)
|
||||||
|
{
|
||||||
|
var ynew = xold;
|
||||||
|
var xnew = newWidth - yold - 1;
|
||||||
|
rotatedLuminances[ynew * newWidth + xnew] = localLuminances[yold * Width + xold];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CreateLuminanceSource(rotatedLuminances, newWidth, newHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns> Whether this subclass supports counter-clockwise rotation.</returns>
|
||||||
|
public override bool RotateSupported
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a new object with cropped image data. Implementations may keep a reference to the
|
||||||
|
/// original data rather than a copy. Only callable if CropSupported is true.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">The left coordinate, 0 <= left < Width.</param>
|
||||||
|
/// <param name="top">The top coordinate, 0 <= top <= Height.</param>
|
||||||
|
/// <param name="width">The width of the rectangle to crop.</param>
|
||||||
|
/// <param name="height">The height of the rectangle to crop.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// A cropped version of this object.
|
||||||
|
/// </returns>
|
||||||
|
public override LuminanceSource crop(int left, int top, int width, int height)
|
||||||
|
{
|
||||||
|
if (left + width > Width || top + height > Height)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Crop rectangle does not fit within image data.");
|
||||||
|
}
|
||||||
|
var croppedLuminances = new sbyte[width * height];
|
||||||
|
for (int yold = top, ynew = 0; yold < height; yold++, ynew++)
|
||||||
|
{
|
||||||
|
for (int xold = left, xnew = 0; xold < width; xold++, xnew++)
|
||||||
|
{
|
||||||
|
croppedLuminances[ynew * width + xnew] = luminances[yold * Width + xold];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CreateLuminanceSource(croppedLuminances, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns> Whether this subclass supports cropping.</returns>
|
||||||
|
public override bool CropSupported
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should create a new luminance source with the right class type.
|
||||||
|
/// The method is used in methods crop and rotate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newLuminances">The new luminances.</param>
|
||||||
|
/// <param name="width">The width.</param>
|
||||||
|
/// <param name="height">The height.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected abstract LuminanceSource CreateLuminanceSource(sbyte[] newLuminances, int width, int height);
|
||||||
|
}
|
||||||
|
public partial class BitmapLuminanceSource : BaseLuminanceSource
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BitmapLuminanceSource"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="width">The width.</param>
|
||||||
|
/// <param name="height">The height.</param>
|
||||||
|
protected BitmapLuminanceSource(int width, int height)
|
||||||
|
: base(width, height)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BitmapLuminanceSource"/> class
|
||||||
|
/// with the image of a Bitmap instance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="bitmap">The bitmap.</param>
|
||||||
|
public BitmapLuminanceSource(Bitmap bitmap)
|
||||||
|
: base(bitmap.Width, bitmap.Height)
|
||||||
|
{
|
||||||
|
var height = bitmap.Height;
|
||||||
|
var width = bitmap.Width;
|
||||||
|
|
||||||
|
// In order to measure pure decoding speed, we convert the entire image to a greyscale array
|
||||||
|
luminances = new sbyte[width * height];
|
||||||
|
|
||||||
|
// The underlying raster of image consists of bytes with the luminance values
|
||||||
|
#if WindowsCE
|
||||||
|
var data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
|
||||||
|
#else
|
||||||
|
var data = bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
|
||||||
|
#endif
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var stride = Math.Abs(data.Stride);
|
||||||
|
var pixelWidth = stride / width;
|
||||||
|
|
||||||
|
if (pixelWidth > 4)
|
||||||
|
{
|
||||||
|
// old slow way for unsupported bit depth
|
||||||
|
Color c;
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
int offset = y * width;
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
c = bitmap.GetPixel(x, y);
|
||||||
|
luminances[offset + x] = (sbyte)(0.3 * c.R + 0.59 * c.G + 0.11 * c.B + 0.01);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var strideStep = data.Stride;
|
||||||
|
var buffer = new byte[stride];
|
||||||
|
var ptrInBitmap = data.Scan0;
|
||||||
|
|
||||||
|
#if !WindowsCE
|
||||||
|
// prepare palette for 1 and 8 bit indexed bitmaps
|
||||||
|
var luminancePalette = new sbyte[bitmap.Palette.Entries.Length];
|
||||||
|
for (var index = 0; index < bitmap.Palette.Entries.Length; index++)
|
||||||
|
{
|
||||||
|
var color = bitmap.Palette.Entries[index];
|
||||||
|
luminancePalette[index] = (sbyte)(0.3 * color.R +
|
||||||
|
0.59 * color.G +
|
||||||
|
0.11 * color.B + 0.01);
|
||||||
|
}
|
||||||
|
if (bitmap.PixelFormat == PixelFormat.Format32bppArgb ||
|
||||||
|
bitmap.PixelFormat == PixelFormat.Format32bppPArgb)
|
||||||
|
{
|
||||||
|
pixelWidth = 40;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
{
|
||||||
|
// copy a scanline not the whole bitmap because of memory usage
|
||||||
|
Marshal.Copy(ptrInBitmap, buffer, 0, stride);
|
||||||
|
#if NET40
|
||||||
|
ptrInBitmap = IntPtr.Add(ptrInBitmap, strideStep);
|
||||||
|
#else
|
||||||
|
ptrInBitmap = new IntPtr(ptrInBitmap.ToInt64() + strideStep);
|
||||||
|
#endif
|
||||||
|
var offset = y * width;
|
||||||
|
switch (pixelWidth)
|
||||||
|
{
|
||||||
|
#if !WindowsCE
|
||||||
|
case 0:
|
||||||
|
for (int x = 0; x * 8 < width; x++)
|
||||||
|
{
|
||||||
|
for (int subX = 0; subX < 8 && 8 * x + subX < width; subX++)
|
||||||
|
{
|
||||||
|
var index = (buffer[x] >> (7 - subX)) & 1;
|
||||||
|
luminances[offset + 8 * x + subX] = luminancePalette[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
luminances[offset + x] = luminancePalette[buffer[x]];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 2:
|
||||||
|
// should be RGB565 or RGB555, assume RGB565
|
||||||
|
{
|
||||||
|
for (int index = 0, x = 0; index < 2 * width; index += 2, x++)
|
||||||
|
{
|
||||||
|
var byte1 = buffer[index];
|
||||||
|
var byte2 = buffer[index + 1];
|
||||||
|
|
||||||
|
var b5 = byte1 & 0x1F;
|
||||||
|
var g5 = (((byte1 & 0xE0) >> 5) | ((byte2 & 0x03) << 3)) & 0x1F;
|
||||||
|
var r5 = (byte2 >> 2) & 0x1F;
|
||||||
|
var r8 = (r5 * 527 + 23) >> 6;
|
||||||
|
var g8 = (g5 * 527 + 23) >> 6;
|
||||||
|
var b8 = (b5 * 527 + 23) >> 6;
|
||||||
|
|
||||||
|
luminances[offset + x] = (sbyte)(0.3 * r8 + 0.59 * g8 + 0.11 * b8 + 0.01);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
var luminance = (sbyte)(0.3 * buffer[x * 3] +
|
||||||
|
0.59 * buffer[x * 3 + 1] +
|
||||||
|
0.11 * buffer[x * 3 + 2] + 0.01);
|
||||||
|
luminances[offset + x] = luminance;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
// 4 bytes without alpha channel value
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
var luminance = (sbyte)(0.30 * buffer[x * 4] +
|
||||||
|
0.59 * buffer[x * 4 + 1] +
|
||||||
|
0.11 * buffer[x * 4 + 2] + 0.01);
|
||||||
|
|
||||||
|
luminances[offset + x] = luminance;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
// with alpha channel; some barcodes are completely black if you
|
||||||
|
// only look at the r, g and b channel but the alpha channel controls
|
||||||
|
// the view
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
{
|
||||||
|
var luminance = (sbyte)(0.30 * buffer[x * 4] +
|
||||||
|
0.59 * buffer[x * 4 + 1] +
|
||||||
|
0.11 * buffer[x * 4 + 2] + 0.01);
|
||||||
|
|
||||||
|
// calculating the resulting luminance based upon a white background
|
||||||
|
// var alpha = buffer[x * pixelWidth + 3] / 255.0;
|
||||||
|
// luminance = (byte)(luminance * alpha + 255 * (1 - alpha));
|
||||||
|
var alpha = buffer[x * 4 + 3];
|
||||||
|
luminance = (sbyte)(((luminance * alpha) >> 8) + (255 * (255 - alpha) >> 8));
|
||||||
|
luminances[offset + x] = luminance;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotSupportedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
bitmap.UnlockBits(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should create a new luminance source with the right class type.
|
||||||
|
/// The method is used in methods crop and rotate.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="newLuminances">The new luminances.</param>
|
||||||
|
/// <param name="width">The width.</param>
|
||||||
|
/// <param name="height">The height.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected override LuminanceSource CreateLuminanceSource(sbyte[] newLuminances, int width, int height)
|
||||||
|
{
|
||||||
|
return new BitmapLuminanceSource(width, height) { luminances = newLuminances };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<Prefer32Bit>false</Prefer32Bit>
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@@ -219,7 +220,7 @@
|
|||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<VisualStudio>
|
<VisualStudio>
|
||||||
<UserProperties BuildVersion_UseGlobalSettings="True" BuildVersion_DetectChanges="False" BuildVersion_BuildAction="ReBuild" BuildVersion_StartDate="2001/1/1" />
|
<UserProperties BuildVersion_StartDate="2001/1/1" BuildVersion_BuildAction="ReBuild" BuildVersion_DetectChanges="False" BuildVersion_UseGlobalSettings="True" />
|
||||||
</VisualStudio>
|
</VisualStudio>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.0304.2046")]
|
[assembly: AssemblyVersion("1.2.0307.1501")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0304.2046")]
|
[assembly: AssemblyFileVersion("1.2.0307.1501")]
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.0304.2046")]
|
[assembly: AssemblyVersion("1.2.0307.1501")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0304.2046")]
|
[assembly: AssemblyFileVersion("1.2.0307.1501")]
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.0304.2046")]
|
[assembly: AssemblyVersion("1.2.0307.1501")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0304.2046")]
|
[assembly: AssemblyFileVersion("1.2.0307.1501")]
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.0304.2046")]
|
[assembly: AssemblyVersion("1.2.0307.1501")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0304.2046")]
|
[assembly: AssemblyFileVersion("1.2.0307.1501")]
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.0304.2046")]
|
[assembly: AssemblyVersion("1.2.0307.1501")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0304.2046")]
|
[assembly: AssemblyFileVersion("1.2.0307.1501")]
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.0304.2046")]
|
[assembly: AssemblyVersion("1.2.0307.1501")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0304.2046")]
|
[assembly: AssemblyFileVersion("1.2.0307.1501")]
|
||||||
|
|||||||
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||||||
// You can specify all the values or you can default the Build and Revision Numbers
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
// [assembly: AssemblyVersion("1.0.*")]
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
[assembly: AssemblyVersion("1.2.0304.2046")]
|
[assembly: AssemblyVersion("1.2.0307.1501")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0304.2046")]
|
[assembly: AssemblyFileVersion("1.2.0307.1501")]
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
var urlImporterUndetectedDelete = '@(Url.Action(MVC.API.DocumentTemplate.ImporterUndetectedDelete()))/';
|
var urlImporterUndetectedDelete = '@(Url.Action(MVC.API.DocumentTemplate.ImporterUndetectedDelete()))/';
|
||||||
var $undetectedPageDialog = $('#undetectedPageDialog').dialog({
|
var $undetectedPageDialog = $('#undetectedPageDialog').dialog({
|
||||||
modal: true,
|
modal: true,
|
||||||
height: 820,
|
height: 850,
|
||||||
width: 800,
|
width: 800,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
autoOpen: false
|
autoOpen: false
|
||||||
@@ -92,7 +92,7 @@
|
|||||||
var oldSelectedIndex = vm.undetectedPages.indexOf(oldSelected);
|
var oldSelectedIndex = vm.undetectedPages.indexOf(oldSelected);
|
||||||
|
|
||||||
if (vm.undetectedPages().length > 1) {
|
if (vm.undetectedPages().length > 1) {
|
||||||
if (oldSelectedIndex > vm.undetectedPages().length - 1)
|
if (oldSelectedIndex + 1 <= vm.undetectedPages().length - 1)
|
||||||
vm.selectedUndetectedPage(vm.undetectedPages()[oldSelectedIndex + 1]);
|
vm.selectedUndetectedPage(vm.undetectedPages()[oldSelectedIndex + 1]);
|
||||||
else
|
else
|
||||||
vm.selectedUndetectedPage(vm.undetectedPages()[oldSelectedIndex - 1]);
|
vm.selectedUndetectedPage(vm.undetectedPages()[oldSelectedIndex - 1]);
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ namespace Disco.Web.Areas.Config.Views.DocumentTemplate
|
|||||||
using Disco.Web;
|
using Disco.Web;
|
||||||
using Disco.Web.Extensions;
|
using Disco.Web.Extensions;
|
||||||
|
|
||||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "1.5.0.0")]
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("RazorGenerator", "1.5.4.0")]
|
||||||
[System.Web.WebPages.PageVirtualPathAttribute("~/Areas/Config/Views/DocumentTemplate/UndetectedPages.cshtml")]
|
[System.Web.WebPages.PageVirtualPathAttribute("~/Areas/Config/Views/DocumentTemplate/UndetectedPages.cshtml")]
|
||||||
public class UndetectedPages : System.Web.Mvc.WebViewPage<Disco.Web.Areas.Config.Models.DocumentTemplate.UndetectedPagesModel>
|
public partial class UndetectedPages : System.Web.Mvc.WebViewPage<Disco.Web.Areas.Config.Models.DocumentTemplate.UndetectedPagesModel>
|
||||||
{
|
{
|
||||||
public UndetectedPages()
|
public UndetectedPages()
|
||||||
{
|
{
|
||||||
@@ -245,7 +245,7 @@ WriteLiteral("/\';\r\n var urlImporterUndetectedDelete = \'");
|
|||||||
#line default
|
#line default
|
||||||
#line hidden
|
#line hidden
|
||||||
WriteLiteral("/\';\r\n var $undetectedPageDialog = $(\'#undetectedPageDialog\').dialog({\r\n " +
|
WriteLiteral("/\';\r\n var $undetectedPageDialog = $(\'#undetectedPageDialog\').dialog({\r\n " +
|
||||||
" modal: true,\r\n height: 820,\r\n width: 800,\r\n " +
|
" modal: true,\r\n height: 850,\r\n width: 800,\r\n " +
|
||||||
" resizable: false,\r\n autoOpen: false\r\n });\r\n\r\n $di" +
|
" resizable: false,\r\n autoOpen: false\r\n });\r\n\r\n $di" +
|
||||||
"alogRemove = $(\'#dialogRemove\').dialog({\r\n resizable: false,\r\n " +
|
"alogRemove = $(\'#dialogRemove\').dialog({\r\n resizable: false,\r\n " +
|
||||||
" height: 140,\r\n modal: true,\r\n autoOpen: false\r\n " +
|
" height: 140,\r\n modal: true,\r\n autoOpen: false\r\n " +
|
||||||
@@ -256,66 +256,66 @@ WriteLiteral("/\';\r\n var $undetectedPageDialog = $(\'#undetectedPageDia
|
|||||||
" self.selectNextPage = function () {\r\n var oldSelected = self.sel" +
|
" self.selectNextPage = function () {\r\n var oldSelected = self.sel" +
|
||||||
"ectedUndetectedPage();\r\n var oldSelectedIndex = vm.undetectedPage" +
|
"ectedUndetectedPage();\r\n var oldSelectedIndex = vm.undetectedPage" +
|
||||||
"s.indexOf(oldSelected);\r\n\r\n if (vm.undetectedPages().length > 1) " +
|
"s.indexOf(oldSelected);\r\n\r\n if (vm.undetectedPages().length > 1) " +
|
||||||
"{\r\n if (oldSelectedIndex > vm.undetectedPages().length - 1)\r\n" +
|
"{\r\n if (oldSelectedIndex + 1 <= vm.undetectedPages().length -" +
|
||||||
" vm.selectedUndetectedPage(vm.undetectedPages()[oldSelect" +
|
" 1)\r\n vm.selectedUndetectedPage(vm.undetectedPages()[oldS" +
|
||||||
"edIndex + 1]);\r\n else\r\n vm.selectedUnd" +
|
"electedIndex + 1]);\r\n else\r\n vm.select" +
|
||||||
"etectedPage(vm.undetectedPages()[oldSelectedIndex - 1]);\r\n } else" +
|
"edUndetectedPage(vm.undetectedPages()[oldSelectedIndex - 1]);\r\n }" +
|
||||||
" {\r\n $undetectedPageDialog.dialog(\'close\');\r\n " +
|
" else {\r\n $undetectedPageDialog.dialog(\'close\');\r\n " +
|
||||||
" vm.selectedUndetectedPage(null);\r\n }\r\n }\r\n " +
|
" vm.selectedUndetectedPage(null);\r\n }\r\n }\r\n " +
|
||||||
"}\r\n\r\n function undetectedPageViewModel(id, timestamp, timestampFuzzy) {\r\n" +
|
" }\r\n\r\n function undetectedPageViewModel(id, timestamp, timestampFuzzy" +
|
||||||
" var self = this;\r\n\r\n self.id = id;\r\n self.time" +
|
") {\r\n var self = this;\r\n\r\n self.id = id;\r\n self" +
|
||||||
"stamp = timestamp;\r\n self.timestampFuzzy = timestampFuzzy;\r\n " +
|
".timestamp = timestamp;\r\n self.timestampFuzzy = timestampFuzzy;\r\n " +
|
||||||
" self.thumbnailUrl = \"url(\" + urlUndetectedPageThumbnail + \"&id=\" + id + \")\";\r" +
|
" self.thumbnailUrl = \"url(\" + urlUndetectedPageThumbnail + \"&id=\" + id + " +
|
||||||
"\n self.previewUrl = \"url(\" + urlUndetectedPagePreview + \"&id=\" + id +" +
|
"\")\";\r\n self.previewUrl = \"url(\" + urlUndetectedPagePreview + \"&id=\" +" +
|
||||||
" \")\";\r\n self.sourceUrl = urlUndetectedPageSource + \"&id=\" + id;\r\n " +
|
" id + \")\";\r\n self.sourceUrl = urlUndetectedPageSource + \"&id=\" + id;\r" +
|
||||||
" self.select = function (e, d) {\r\n vm.selectedUndetectedPa" +
|
"\n self.select = function (e, d) {\r\n vm.selectedUndetec" +
|
||||||
"ge(self);\r\n $undetectedPageDialog.dialog(\'open\');\r\n }\r" +
|
"tedPage(self);\r\n $undetectedPageDialog.dialog(\'open\');\r\n " +
|
||||||
"\n\r\n // Dialog Properties\r\n self.dialogTemplateId = ko.obse" +
|
" }\r\n\r\n // Dialog Properties\r\n self.dialogTemplateId = ko" +
|
||||||
"rvable(null);\r\n self.dialogDataId = ko.observable(null);\r\n " +
|
".observable(null);\r\n self.dialogDataId = ko.observable(null);\r\n " +
|
||||||
" self.dialogDataIdService = ko.computed(function () {\r\n return ur" +
|
" self.dialogDataIdService = ko.computed(function () {\r\n retu" +
|
||||||
"lDataIdLookupService + self.dialogTemplateId();\r\n });\r\n se" +
|
"rn urlDataIdLookupService + self.dialogTemplateId();\r\n });\r\n " +
|
||||||
"lf.deletePage = function () {\r\n $undetectedPageDialog.dialog(\'opt" +
|
" self.deletePage = function () {\r\n $undetectedPageDialog.dialog" +
|
||||||
"ion\', \'disabled\', true);\r\n\r\n $dialogRemove.dialog(\'option\', \'butt" +
|
"(\'option\', \'disabled\', true);\r\n\r\n $dialogRemove.dialog(\'option\', " +
|
||||||
"ons\', {\r\n \"Remove\": function () {\r\n $d" +
|
"\'buttons\', {\r\n \"Remove\": function () {\r\n " +
|
||||||
"ialogRemove.dialog(\"close\");\r\n var data = { id: self.id }" +
|
" $dialogRemove.dialog(\"close\");\r\n var data = { id: self" +
|
||||||
";\r\n $.ajax({\r\n url: urlImporte" +
|
".id };\r\n $.ajax({\r\n url: urlIm" +
|
||||||
"rUndetectedDelete,\r\n dataType: \'json\',\r\n " +
|
"porterUndetectedDelete,\r\n dataType: \'json\',\r\n " +
|
||||||
" data: data,\r\n type: \'POST\',\r\n " +
|
" data: data,\r\n type: \'POST\',\r\n " +
|
||||||
" success: function (d) {\r\n if (" +
|
" success: function (d) {\r\n " +
|
||||||
"d == \'OK\') {\r\n vm.selectNextPage();\r\n " +
|
" if (d == \'OK\') {\r\n vm.selectNextPage();\r\n " +
|
||||||
" vm.undetectedPages.remove(self);\r\n " +
|
" vm.undetectedPages.remove(self);\r\n " +
|
||||||
" } else {\r\n alert(\'Unable to del" +
|
" } else {\r\n alert(\'Unable t" +
|
||||||
"ete page: \' + d);\r\n }\r\n " +
|
"o delete page: \' + d);\r\n }\r\n " +
|
||||||
" $undetectedPageDialog.dialog(\'option\', \'disabled\', false);\r\n " +
|
" $undetectedPageDialog.dialog(\'option\', \'disabled\', false);\r\n " +
|
||||||
" },\r\n error: function (jqXHR, textStatus" +
|
" },\r\n error: function (jqXHR, textS" +
|
||||||
", errorThrown) {\r\n alert(\'Unable to delete page: " +
|
"tatus, errorThrown) {\r\n alert(\'Unable to delete p" +
|
||||||
"\' + errorThrown);\r\n $undetectedPageDialog.dialog(" +
|
"age: \' + errorThrown);\r\n $undetectedPageDialog.di" +
|
||||||
"\'option\', \'disabled\', false);\r\n }\r\n " +
|
"alog(\'option\', \'disabled\', false);\r\n }\r\n " +
|
||||||
" });\r\n },\r\n \"Cancel\": function () {\r\n" +
|
" });\r\n },\r\n \"Cancel\": function (" +
|
||||||
" $dialogRemove.dialog(\"close\");\r\n " +
|
") {\r\n $dialogRemove.dialog(\"close\");\r\n " +
|
||||||
"$undetectedPageDialog.dialog(\'option\', \'disabled\', false);\r\n " +
|
" $undetectedPageDialog.dialog(\'option\', \'disabled\', false);\r\n " +
|
||||||
"}\r\n });\r\n\r\n $dialogRemove.dialog(\'open\');\r\n\r\n " +
|
" }\r\n });\r\n\r\n $dialogRemove.dialog(\'open\');\r\n\r\n" +
|
||||||
" return false;\r\n }\r\n self.assignPage = function " +
|
" return false;\r\n }\r\n self.assignPage = func" +
|
||||||
"() {\r\n var dtId = self.dialogTemplateId();\r\n var d" +
|
"tion () {\r\n var dtId = self.dialogTemplateId();\r\n " +
|
||||||
"Id = self.dialogDataId();\r\n if (!dtId || !dId) {\r\n " +
|
"var dId = self.dialogDataId();\r\n if (!dtId || !dId) {\r\n " +
|
||||||
" alert(\'Please specify a valid Document Type and Data Id\');\r\n " +
|
" alert(\'Please specify a valid Document Type and Data Id\');\r\n " +
|
||||||
" } else {\r\n $undetectedPageDialog.dialog(\'option\', \'disabled\'" +
|
" } else {\r\n $undetectedPageDialog.dialog(\'option\', \'disa" +
|
||||||
", true);\r\n\r\n var data = { id: self.id, DocumentTemplateId: dt" +
|
"bled\', true);\r\n\r\n var data = { id: self.id, DocumentTemplateI" +
|
||||||
"Id, DataId: dId };\r\n\r\n $.ajax({\r\n url:" +
|
"d: dtId, DataId: dId };\r\n\r\n $.ajax({\r\n " +
|
||||||
" urlImporterUndetectedAssign,\r\n dataType: \'json\',\r\n " +
|
" url: urlImporterUndetectedAssign,\r\n dataType: \'json\',\r\n " +
|
||||||
" data: data,\r\n type: \'POST\',\r\n " +
|
" data: data,\r\n type: \'POST\',\r\n " +
|
||||||
" success: function (d) {\r\n if (d == \'OK\'" +
|
" success: function (d) {\r\n if (d ==" +
|
||||||
") {\r\n vm.selectNextPage();\r\n " +
|
" \'OK\') {\r\n vm.selectNextPage();\r\n " +
|
||||||
" vm.undetectedPages.remove(self);\r\n } else " +
|
" vm.undetectedPages.remove(self);\r\n } " +
|
||||||
"{\r\n alert(\'Unable to assign page: \' + d);\r\n " +
|
"else {\r\n alert(\'Unable to assign page: \' + d);\r\n " +
|
||||||
" }\r\n $undetectedPageDialog.dialo" +
|
" }\r\n $undetectedPageDialog." +
|
||||||
"g(\'option\', \'disabled\', false);\r\n },\r\n " +
|
"dialog(\'option\', \'disabled\', false);\r\n },\r\n " +
|
||||||
" error: function (jqXHR, textStatus, errorThrown) {\r\n " +
|
" error: function (jqXHR, textStatus, errorThrown) {\r\n " +
|
||||||
" alert(\'Unable to assign page: \' + errorThrown);\r\n " +
|
" alert(\'Unable to assign page: \' + errorThrown);\r\n " +
|
||||||
" $undetectedPageDialog.dialog(\'option\', \'disabled\', false);\r\n " +
|
" $undetectedPageDialog.dialog(\'option\', \'disabled\', false);\r\n " +
|
||||||
" }\r\n });\r\n\r\n }\r\n return fa" +
|
" }\r\n });\r\n\r\n }\r\n retu" +
|
||||||
"lse;\r\n };\r\n }\r\n\r\n function init() {\r\n vm = n" +
|
"rn false;\r\n };\r\n }\r\n\r\n function init() {\r\n v" +
|
||||||
"ew pageViewModel();\r\n\r\n $.ajax({\r\n url: \'");
|
"m = new pageViewModel();\r\n\r\n $.ajax({\r\n url: \'");
|
||||||
|
|
||||||
|
|
||||||
#line 202 "..\..\Areas\Config\Views\DocumentTemplate\UndetectedPages.cshtml"
|
#line 202 "..\..\Areas\Config\Views\DocumentTemplate\UndetectedPages.cshtml"
|
||||||
|
|||||||
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
|
|||||||
//
|
//
|
||||||
// You can specify all the values or you can default the Revision and Build Numbers
|
// You can specify all the values or you can default the Revision and Build Numbers
|
||||||
// by using the '*' as shown below:
|
// by using the '*' as shown below:
|
||||||
[assembly: AssemblyVersion("1.2.0304.2046")]
|
[assembly: AssemblyVersion("1.2.0307.1501")]
|
||||||
[assembly: AssemblyFileVersion("1.2.0304.2046")]
|
[assembly: AssemblyFileVersion("1.2.0307.1501")]
|
||||||
|
|||||||
Reference in New Issue
Block a user