End to end tests, configurable output directory, fix bounds

master
Justin Bass 4 years ago
parent a3d137efbd
commit e030ae4266
  1. 1
      .gitignore
  2. 6
      colorsafe/cmd.py
  3. 28
      colorsafe/colorsafe.py
  4. 1
      colorsafe/csdecoder.py
  5. 18
      colorsafe/csencoder.py
  6. 5
      setup.py
  7. 47
      test/test_e2e.py
  8. 3
      test/test_unit.py

1
.gitignore vendored

@ -8,3 +8,4 @@ dist
ignore
.DS_STORE
.idea
.pytest_cache

@ -7,7 +7,7 @@ import argparse
def encode(args):
ColorSafeEncoder(args.filename, args.colorDepth, args.pageHeight, args.pageWidth, args.borderTop, args.borderBottom,
args.borderLeft, args.borderRight, args.dotFillPixels, args.pixelsPerDot, args.printerDpi,
args.saveImages)
args.outPath, args.saveImages, args.noPdf)
def decode(args):
ColorSafeDecoder(args.filenames, args.colorDepth, args.outfile, args.saveMetadata)
@ -42,8 +42,12 @@ def main():
help='Left border of output pages (in)')
encoder_parser.add_argument('-br', '--borderRight', type=float, default=0.1, \
help='Right border of output pages (in)')
encoder_parser.add_argument('-o', '--outPath', type=str, default="", \
help='Output file path, for pdf and images')
encoder_parser.add_argument('--saveImages', action='store_true', default=False, \
help='Also output the individual png files')
encoder_parser.add_argument('--noPdf', action='store_true', default=False, \
help='Don\'t save the PDF file by default')
encoder_parser.set_defaults(func=encode)

@ -1142,6 +1142,10 @@ class ColorSafeImageFiles:
heightPerDot = float(bottomTemp - topTemp + 1) / (sectorHeight + 2 * gapSize)
widthPerDot = float(rightTemp - leftTemp + 1) / (sectorWidth + 2 * gapSize)
if widthPerDot < 1.0: # Less than 1.0x resolution, cannot get all dots
# TODO: Throw error
return
# Find real gaps, since small rotation across a large page may distort this.
# Look within one-dot unit of pixels away
bottommostTop = topTemp + int(round(heightPerDot))
@ -1209,10 +1213,6 @@ class ColorSafeImageFiles:
# Find the most likely dot start locations, TODO: Combine into one function
avgPixelsWidth = int(round(widthPerDot))
if widthPerDot < 1.0: # Less than 1.0x resolution, cannot get all dots
# TODO: Throw error, move further up in this function
return
if widthPerDot == 1.0: # Exactly 1.0, e.g. original output, or perfectly scanned
maxPixelsWidth = 1
else:
@ -1558,6 +1558,7 @@ class ColorSafeImageFiles:
lowBorderThreshold = 0.35
highGapThreshold = 0.65
diffThreshold = 0.1 # Threshold for throwing out a value and using the mode end-begin diff instead
# Trim leading/trailing whitespace for better min/max normalization
borderBeginning = 0
@ -1612,6 +1613,25 @@ class ColorSafeImageFiles:
if len(begins) > len(ends):
begins = begins[0:len(ends)]
# Correct bounds
if len(begins) > 1:
beginsDiffs = list()
endsDiffs = list()
for i in range(1, len(begins)):
beginsDiffs.append(begins[i] - begins[i-1])
endsDiffs.append(ends[i] - ends[i-1])
beginsDiffsMode = max(beginsDiffs, key=beginsDiffs.count)
endsDiffsMode = max(endsDiffs, key=endsDiffs.count)
# TODO: Doesn't correct first begin or end - assumes first one is correct
for i in range(1, len(begins)):
if abs(begins[i] - begins[i - 1]) / float(beginsDiffsMode) > diffThreshold:
begins[i] = begins[i - 1] + beginsDiffsMode
if abs(ends[i] - ends[i - 1]) / float(endsDiffsMode) > diffThreshold:
ends[i] = ends[i - 1] + endsDiffsMode
bounds = list()
for i in range(0, len(begins)):
bounds.append((begins[i], ends[i]))

@ -6,7 +6,6 @@ MaxColorVal = 255
pagePixels = list()
def getPageGrayPixel(pageNum, y, x, pagePixels, grayscale = True):
#print pageNum, pagePixels, x, y
pixel = pagePixels[pageNum][x,y]
if grayscale:

@ -41,7 +41,9 @@ class ColorSafePdfFile:
filename = Defaults.filename,
printerDpi = printerDpi,
fileExtension = Defaults.fileExtension,
saveImages = False):
outPath = "",
saveImages = False,
noPdf = False):
self.printerDpi = printerDpi
self.pageHeight = pageHeight
@ -52,6 +54,7 @@ class ColorSafePdfFile:
self.borderRight = borderRight
self.pixelsPerDot = pixelsPerDot
self.outPath = outPath
self.getPageProperties()
@ -75,7 +78,7 @@ class ColorSafePdfFile:
imageFilenames = list()
for i,image in enumerate(csImages.images):
outputFilename = self.FilenameFormat % (csImages.filename, i, self.ImageExtension)
outputFilename = os.path.join(outPath, self.FilenameFormat % (csImages.filename, i, self.ImageExtension))
imageFilenames.append(outputFilename)
imagePIL = Image.new('RGB', (len(image[0]),len(image)), "white")
pixelsPIL = imagePIL.load() # create the pixel map
@ -87,7 +90,8 @@ class ColorSafePdfFile:
self.csImages = csImages
self.getPdfFile()
if not noPdf:
self.getPdfFile()
for f in imageFilenames:
if not saveImages:
@ -108,7 +112,7 @@ class ColorSafePdfFile:
pdfHeight = self.csImages.workingHeightPixels+headerPaddingPixels
headerYVal = pdfHeight - headerPaddingPixels/2
pdfFilename = self.csImages.filename + "." + self.PdfExtension
pdfFilename = os.path.join(self.outPath, self.csImages.filename + "." + self.PdfExtension)
c = canvas.Canvas(pdfFilename)
c.setPageSize((pdfWidth,pdfHeight))
@ -129,7 +133,7 @@ class ColorSafePdfFile:
class ColorSafeEncoder:
def __init__(self, filename, colorDepth, pageHeight, pageWidth, borderTop, borderBottom, borderLeft, borderRight,
dotFillPixels, pixelsPerDot, printerDpi, saveImages):
dotFillPixels, pixelsPerDot, printerDpi, outPath, saveImages, noPdf):
fileHandle = open(filename)
mm = mmap.mmap(fileHandle.fileno(), 0, prot=mmap.PROT_READ)
@ -145,7 +149,9 @@ class ColorSafeEncoder:
dotFillPixels = dotFillPixels,
pixelsPerDot = pixelsPerDot,
printerDpi = printerDpi,
saveImages = saveImages)
outPath = outPath,
saveImages = saveImages,
noPdf = noPdf)
fileHandle.close()

@ -1,6 +1,6 @@
from setuptools import setup, find_packages
VERSION_NAME = '0.1.0.dev5'
VERSION_NAME = '0.1.0.dev6'
setup(
name = 'colorsafe',
@ -18,7 +18,8 @@ setup(
install_requires = [
'unireedsolomon',
'reportlab',
'pillow'
'pillow',
'pytest'
],
classifiers = [],
)

@ -0,0 +1,47 @@
from colorsafe import ColorSafeEncoder, ColorSafeDecoder
import os
import pytest
text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sollicitudin tincidunt diam id gravida." \
"Integer gravida risus quis purus bibendum volutpat. Fusce nec scelerisque ipsum. Curabitur nec augue ac" \
"nulla aliquet gravida ut quis justo. Aliquam sagittis nec arcu consectetur fermentum. Duis consectetur" \
"convallis pharetra. Nullam porttitor mi quis risus rhoncus malesuada nec vitae ex. Nunc non mattis justo." \
"Sed pellentesque, nulla vitae sagittis pulvinar, massa dui pellentesque sapien, vel dignissim lorem nisi sit" \
"amet augue. Nam rhoncus leo non urna sodales, vitae elementum magna viverra. Aliquam aliquam eu neque vel" \
"dictum. Nulla fermentum placerat elit. Vivamus non augue congue, maximus sem non, mollis nulla. Donec non" \
"elit purus."
# Test defaults
defaults = [(1, 11, 8.5, 0.2, 0.1, 0.1, 0.1, 1, 1, 100, ["out_0.png"], "out.txt")]
@pytest.mark.parametrize("color_depth,page_height,page_width,border_top,border_bottom,border_left,border_right,"
"dot_fill_pixels,pixels_per_dot,printer_dpi,out_image_names,out_file_name",
defaults)
def test_encode_decode(tmpdir, color_depth, page_height, page_width, border_top, border_bottom, border_left,
border_right, dot_fill_pixels, pixels_per_dot, printer_dpi,
out_image_names, out_file_name):
"""Encode a text file, then decode it and compare the contents to the original file.
"""
in_file_name = "text.txt"
in_file = tmpdir.join(in_file_name)
in_file.write(text)
ColorSafeEncoder(str(in_file), color_depth, page_height, page_width, border_top, border_bottom, border_left,
border_right, dot_fill_pixels, pixels_per_dot, printer_dpi, str(tmpdir), True, True)
out_file = tmpdir.join(out_file_name)
out_image_paths = list()
for name in out_image_names:
out_image_path = tmpdir.join(name)
out_image_paths.append(str(out_image_path))
ColorSafeDecoder(out_image_paths, color_depth, str(out_file), False)
out_file_contents = out_file.read()
assert len(out_file_contents) > 0
assert text == out_file_contents

@ -1,6 +1,3 @@
import sys, os
sys.path.append(os.path.realpath(os.path.dirname(__file__)+"/.."))
from colorsafe.colorsafe import Constants, ColorChannels, Dot, DotByte, DotRow
MaxColorVal = 255
Loading…
Cancel
Save