Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

massive docs refactor

  • Loading branch information...
commit 780b02a6b124c32bca84785ba22ca412bace5969 1 parent 0308143
@ojii authored
View
741 docs/dev/api.rst
@@ -0,0 +1,741 @@
+############
+Internal API
+############
+
+
+.. module:: pymaging.image
+
+*********************
+:mod:`pymaging.image`
+*********************
+
+
+.. class:: Image(pixelarray, mode, palette=None)
+
+ The image class. This is the core class of pymaging.
+
+ :param pixelarray: An instance of :class:`pymaging.pixelarray.GenericPixelArray` or a subclass of it.
+ :param mode: The color mode. A :class:`pymaging.color.ColorType` instance.
+ :param palette: If given, this will be the color palette used by the image. A list of :class:`pymaging.color.Color`
+ instances.
+
+ .. attribute:: mode
+
+ The color mode used in this image. A :class:`pymaging.color.ColorType` instance.
+
+ .. attribute:: palette
+
+ The palette used in this image. A list of :class:`pymaging.color.Color` instances or ``None``.
+
+ .. attribute:: reverse_palette
+
+ Cache for :meth:`get_reverse_palette`.
+
+ .. attribute:: pixels
+
+ The :class:`pymaging.pixelarray.GenericPixelArray` (or subclass thereof) instance holding the image data.
+
+ .. attribute:: width
+
+ The width of the image (in pixels)
+
+ .. attribute:: height
+
+ The height of the image (in pixels)
+
+ .. attribute:: pixelsize
+
+ The size of a pixel (in :attr:`pixels`). ``1`` usually indicates an image with a palette. ``3`` is an standard
+ RGB image. ``4`` is a RGBA image.
+
+ .. classmethod:: open(fileobj)
+
+ Creates a new image from a file object
+
+ :param fileobj: A file like object open for reading.
+
+ .. classmethod:: open_from_path(filepath)
+
+ Creates a new image from a file path
+
+ :param fileobj: A string pointing at a image file.
+
+ .. method:: save(fileobj, format)
+
+ Saves the image.
+
+ :param fileobj: A file-like object (opened for writing) to which the image should be saved.
+ :param format: The format to use for saving (as a string).
+
+ .. method:: save_to_path(filepath, format=None):
+
+ Saves the image to a path.
+
+ :param filepath: A string pointing at a (writable) file location where the image should be saved.
+ :param format: If given, the format (string) to use for saving. If ``None``, the format will be guessed from
+ the file extension used in ``filepath``.
+
+ .. method:: get_reverse_palette
+
+ Returns :attr:`reverse_palette`. If :attr:`reverse_palette` is ``None``, calls :meth:`_fill_reverse_palette`.
+ The reverse palette is a dictionary. If the image has no palette, an empty dictionary is returned.
+
+ .. method:: _fill_reverse_palette
+
+ Populates the reverse palette, which is a mapping of :class:`pymaging.color.Color` instances to their index in
+ the palette. Sets :attr:`reverse_palette`.
+
+ .. method:: resize(width, height, resample_algorithm=nearest, resize_canvas=True)
+
+ Resizes the image to the given ``width`` and ``height``, using given ``resample_algorithm``. If
+ ``resize_canvas`` is ``False``, the actual image dimensions do not change, in which case the excess pixels will
+ be filled by a background color (usually black). Returns the resized copy of this image.
+
+ :param width: The new width as integer in pixels.
+ :param height: The new height as integer in pixels.
+ :param resample_algorithm: The resample algorithm to use. Should be a :class:`pymaging.resample.Resampler`
+ instance.
+ :param resize_canvas: Boolean flag whether to resize the canvas or not.
+
+ .. method:: affine(transform, resample_algorithm=nearest, resize_canvas=True)
+
+ Advanced version of :meth:`resize`. Instead of a ``height`` and ``width``, a
+ :class:`pymaging.affine.AffineTransform` is passed according to which the image is transformed.
+ Returns the transformed copy of the image.
+
+ .. method:: rotate(degrees, clockwise=False, resample_algorithm=nearest, resize_canvas=True)
+
+ Rotates the image by ``degrees`` degrees counter-clockwise (unless ``clockwise`` is ``True``). Interpolation of
+ the pixels is done using ``resample_algorithm``. Returns the rotated copy of this image.
+
+ .. method:: get_pixel(x, y)
+
+ Returns the pixel at the given ``x``/``y`` location. If the pixel is outside the image, raises an
+ :exc:`IndexError`. If the image has a palette, the palette lookup will be performed by this method. The pixel is
+ returned as a list if integers.
+
+ .. method:: get_color(x, y)
+
+ Same as :meth:`get_pixel` but returns a :class:`pymaging.colors.Color` instance.
+
+ .. method:: set_color(x, y, color)
+
+ The core drawing API. This should be used to draw pixels to the image. Sets the pixel at ``x``/``y`` to the
+ color given. The color should be a :class:`pymaging.colors.Color` instance. If the image has a palette, only
+ colors that are in the palette are supported.
+
+ .. method:: flip_top_bottom
+
+ Vertically flips the image and returns the flipped copy.
+
+ .. method:: flip_left_right
+
+ Horizontally flips the image and returns the flipped copy.
+
+ .. method:: crop(width, height, padding_top, padding_left)
+
+ Crops the pixel to the new ``width`` and ``height``, starting the cropping at the offset given with
+ ``padding_top`` and ``padding_left``. Returns the cropped copy of this image.
+
+ .. method:: draw(shape, color)
+
+ Draws the shape using the given color to this image. The shape should be a :class:`pymaging.shapes.BaseShape`
+ subclass instance, or any object that has a ``iter_pixels`` method, which when called with a
+ :class:`pymaging.colors.Color` instance, returns an iterator that yields tuples of ``(x, y, color)`` of colors
+ to be drawn to pixels.
+
+ This method is just a shortcut around :meth:`set_color` which allows users to write shape classes that do the
+ heavy lifting for them.
+
+ This method operates **in place** and does not return a copy of this image!
+
+
+.. module:: pymaging.affine
+
+**********************
+:mod:`pymaging.affine`
+**********************
+
+
+.. class:: AffineTransform(matrix)
+
+ Affine transformation matrix. Used by :meth:`pymaging.image.Image.affine`.
+
+ The matrix should be given either as a sequence of 9 values or a sequence of 3 sequences of 3 values.
+
+ .. TODO:: Needs documentation about the actual values of the matrix.
+
+ .. attribute:: matrix
+
+ .. TODO:: Needs documentation.
+
+ .. method:: _determinant
+
+ .. TODO:: Needs documentation.
+
+ .. method:: inverse
+
+ .. TODO:: Needs documentation.
+
+ .. method:: rotate(degrees, clockwise=False)
+
+ .. TODO:: Needs documentation.
+
+ .. method:: scale(x_factor, y_factor=None)
+
+ .. TODO:: Needs documentation.
+
+ .. method:: translate(dx, dy)
+
+ .. TODO:: Needs documentation.
+
+
+.. module:: pymaging.colors
+
+**********************
+:mod:`pymaging.colors`
+**********************
+
+.. function:: _mixin_alpha(colors, alpha)
+
+ Applies the given alpha value to all colors. Colors should be a list of three items: ``r``, ``g`` and ``b``.
+
+
+.. class:: Color(red, green, blue alpha)
+
+ Represents a color. All four parameters should be integers between 0 and 255.
+
+ .. attribute:: red
+ .. attribute:: green
+ .. attribute:: blue
+ .. attribute:: alpha
+
+ .. classmethod:: from_pixel(pixel)
+
+ Given a pixel (a list of colors), create a :class:`Color` instance.
+
+ .. classmethod:: from_hexcode(hexcode)
+
+ Given a hexcode (a string of 3, 4, 6 or 8 characters, optionally prefixed by ``'#'``), construct a
+ :class:`Color` instance.
+
+ .. method:: get_for_brightness(brightness)
+
+ Given a brightness (alpha value) between 0 and 1, return the current color for that brightness.
+
+ .. method:: cover_with(cover_color)
+
+ Covers the current color with another color respecting their respective alpha values. If the ``cover_color``
+ is a solid color, return a copy of the ``cover_color``. ``cover_color`` must be an instance of :class:`Color`.
+
+ .. method:: to_pixel(pixelsize)
+
+ Returns this color as a pixel (list of integers) for the given ``pixelsize`` (3 or 4).
+
+ .. method:: to_hexcode
+
+ Returns this color as RGBA hexcode. (Without leading ``'#'``).
+
+
+.. class:: ColorType
+
+ A named tuple holding the length of a color type (pixelsize) and whether this color type supports the alpha channel
+ or not.
+
+ .. attribute:: length
+ .. attribute:: alpha
+
+
+.. data:: RGB
+
+ RGB :class:`ColorType`.
+
+.. data:: RGBA
+
+ RGBA :class:`ColorType`.
+
+
+.. module:: pymaging.exceptions
+
+*************************
+:mod:`pymaging.exception`
+*************************
+
+
+.. exception:: PymagingExcpetion
+
+ The root exception type for all exceptions defined in this module.
+
+.. exception:: FormatNotSupported
+
+ Raised if an image is saved or loaded in a format not supported by pymaging.
+
+.. exception:: InvalidColor
+
+ Raised if an invalid color is used on an image (usually when the image has a palette).
+
+
+.. module:: pymaging.formats
+
+***********************
+:mod:`pymaging.formats`
+***********************
+
+Loads and maintains the formats supported in this installation.
+
+.. class:: Format(decode, encode, extensions)
+
+ A named tuple that should be used to define formats for pymaging. ``decode`` and ``encode`` are callables that
+ decode and encode an image in this format. ``extensions`` is a list of file extensions this image type could have.
+
+ .. attribute:: decode
+ .. attribute:: encode
+ .. attribute:: extensions
+
+.. class:: FormatRegistry
+
+ A singleton class for format registration
+
+ .. method:: _populate
+
+ Populates the registry using package resources.
+
+ .. method:: register(format)
+
+ Manually registers a format, which must be an instance of :class:`Format`.
+
+ .. method:: get_format_objects
+
+ Returns all formats in this registry.
+
+ .. method:: get_format(format)
+
+ Given a format name (eg file extension), returns the :class:`Format` instance if it's registered, otherwise
+ ``None``.
+
+.. data:: registry
+
+ The singleton instance of :class:`FormatRegistry`.
+
+.. function:: get_format_objects
+
+ Shortcut to :data:`registry.get_format_objects`.
+
+.. function:: get_format
+
+ Shortcut to :data:`registry.get_format`.
+
+.. function:: register
+
+ Shortcut to :data:`registry.register`.
+
+
+.. module:: pymaging.helpers
+
+***********************
+:mod:`pymaging.helpers`
+***********************
+
+
+.. function:: get_transformed_dimensions(transform, box)
+
+ Takes an affine transform and a four-tuple of (x0, y0, x1, y1) coordinates. Transforms each corner of the given box,
+ and returns the (width, height) of the transformed box.
+
+
+.. module:: pymaging.pixelarray
+
+**************************
+:mod:`pymaging.pixelarray`
+**************************
+
+
+.. class:: GenericPixelArray(data, width, height, pixelsize)
+
+ The base pixel array class. ``data`` should be a flat :class:`array.array` instance of pixel data, ``width`` and
+ ``height`` are the dimensions of the array and ``pixelsize`` defines how many items in the ``data`` array define a
+ single pixel.
+
+ Use :func:`get_pixel_array` to instantiate this class!
+
+ .. attribute:: data
+
+ The image data as array.
+
+ .. attribute:: width
+
+ The width of the pixel array.
+
+ .. attribute:: height
+
+ The height of the pixel array.
+
+ .. attribute:: pixelsize
+
+ The size of a single pixel
+
+ .. attribute:: line_length
+
+ The length of a line. (:attr:`width` multiplied with :attr:`pixelsize`).
+
+ .. attribute:: size
+
+ The size of the pixel array.
+
+ .. method:: _precalculate
+
+ Precalculates :attr:`line_width` and :attr:`size`. Should be called whenever :attr:`width`, :attr:`height` or
+ :attr:`pixelsize` change.
+
+ .. method:: _translate(x, y)
+
+ Translates the logical ``x``/``y`` coordinates into the start of the pixel in the pixel array.
+
+ .. method:: get(x, y)
+
+ Returns the pixel at ``x``/``y`` as list of integers.
+
+ .. method:: set(x, y, pixel)
+
+ Sets the ``pixel`` to ``x``/``y``.
+
+ .. method:: copy_flipped_top_bottom
+
+ Returns a copy of this pixel array with the lines flipped from top to bottom.
+
+ .. method:: copy_flipped_left_right
+
+ Returns a copy of this pixel array with the lines flipped from left to right.
+
+ .. method:: copy
+
+ Returns a copy of this pixel array.
+
+ .. method:: remove_lines(offset, amount)
+
+ Removes ``amount`` lines from this pixel array after ``offset`` (from the top).
+
+ .. method:: remove_columns(offset, amount)
+
+ Removes ``amount`` columns from this pixel array after ``offset`` (from the left).
+
+ .. note::
+
+ If :meth:`remove_columns` and :meth:`remove_lines` are used together, :meth:`remove_lines` should always be
+ called first, as that method is a lot faster and :meth:`remove_columns` gets faster the fewer lines there
+ are in a pixel array.
+
+ .. method:: add_lines(offset, amount, fill=0)
+
+ Adds ``amount`` lines to the pixel array after ``offset`` (from the top) and fills it with ``fill``.
+
+ .. method:: add_columns(offset, amount, fill=0)
+
+ Adds ``amount`` columns to the pixel array after ``offset`` (from the left) and fill it with ``fill``.
+
+ .. note::
+
+ As with :meth:`remove_columns`, the cost of this method grows with the amount of lines in the pixe array.
+ If it is used together with :meth:`add_lines`, :meth:`add_columns` should be called first.
+
+
+.. class:: PixelArray1(data, width, height)
+
+ Subclass of :class:`GenericPixelArray`, optimized for pixelsize 1.
+
+ Use :func:`get_pixel_array` to instantiate this class!
+
+.. class:: PixelArray2(data, width, height)
+
+ Subclass of :class:`GenericPixelArray`, optimized for pixelsize 2.
+
+ Use :func:`get_pixel_array` to instantiate this class!
+
+
+.. class:: PixelArray3(data, width, height)
+
+ Subclass of :class:`GenericPixelArray`, optimized for pixelsize 3.
+
+ Use :func:`get_pixel_array` to instantiate this class!
+
+
+.. class:: PixelArray4(data, width, height)
+
+ Subclass of :class:`GenericPixelArray`, optimized for pixelsize 4.
+
+ Use :func:`get_pixel_array` to instantiate this class!
+
+
+.. function:: get_pixel_array(data, width, height, pixelsize)
+
+ Returns the most optimal pixel array class for the given pixelsize. Use this function instead of instantating the
+ pixel array classes directly.
+
+
+.. module:: pymaging.resample
+
+************************
+:mod:`pymaging.resample`
+************************
+
+
+.. class:: Resampler
+
+ Base class for resampler algorithms. Should never be instantated directly.
+
+ .. method:: affine(source, transform, resize_canvas=True)
+
+ .. TODO:: Document.
+
+ .. method:: resize(source, width, height, resize_canvas=True)
+
+ .. TODO:: Document.
+
+
+.. class:: Nearest
+
+ Subclass of :class:`Resampler`. Implements the nearest neighbor resampling algorithm which is very fast but creates
+ very ugly resampling artifacts.
+
+
+.. class:: Bilinear
+
+ Subclass of :class:`Resampler` implementing the bilinear resampling algorithm, which produces much nicer results at
+ the cost of computation time.
+
+
+.. data:: nearest
+
+ Singleton instance of the :class:`Nearest` resampler.
+
+
+.. data:: bilinear
+
+ Singleton instance of the :class:`Bilinear` resampler.
+
+
+.. module:: pymaging.shapes
+
+**********************
+:mod:`pymaging.shapes`
+**********************
+
+
+Shapes are the high level drawing API used by :meth:`pymaging.image.Image.draw`.
+
+
+.. class:: BaseShape
+
+ Dummy base class for shapes.
+
+ .. method:: iter_pixels(color)
+
+ In subclasses, this is the API used by :meth:`pymaging.image.Image.draw` to draw to an image. Should return an
+ iterator that yields ``x``, ``y``, ``color`` tuples.
+
+
+.. class:: Pixel(x, y)
+
+ A simple single-pixel drawing object.
+
+
+.. class:: Line(start_x, start_y, end_x, end_y)
+
+ Simple line drawing algorithm using the Bresenham Line Algorithm. Draws non-anti-aliased lines, which is very fast
+ but for lines that are not exactly horizontal or vertical, this produces rather ugly lines.
+
+
+.. class:: AntiAliasedLine(start_x, start_y, end_x, end_y)
+
+ Draws an anti-aliased line using Xiaolin Wu's line algorithm. This has a lot higher computation costs than
+ :class:`Line` but produces much nicer results. When used on an image with a palette, this shape might cause errors.
+
+
+.. module:: pymaging.test_utils
+
+**************************
+:mod:`pymaging.test_utils`
+**************************
+
+
+.. function:: image_factory(colors, alpha=True)
+
+ Creates an image given a list of lists of :class:`pymaging.color.Color` instances. The ``alpha`` parameter defines
+ the pixel size of the image.
+
+
+.. class:: PymagingBaseTestCase
+
+ .. method:: assertImage(image, colors, alpha=True)
+
+ Checks that an image is the same as the dummy image given. ``colors`` and ``alpha`` are passed to
+ :func:`image_factory` to create a comparison image.
+
+
+.. module:: pymaging.utils
+
+*********************
+:mod:`pymaging.utils`
+*********************
+
+
+.. function:: fdiv(a, b)
+
+ Does a float division of ``a`` and ``b`` regardless of their type and returns a float.
+
+
+.. function:: get_test_file(testfile, fname)
+
+ Returns the full path to a file for a given test.
+
+
+.. module:: pymaging.webcolors
+
+*************************
+:mod:`pymaging.webcolors`
+*************************
+
+
+Defines constant :class:`pymaging.color.Color` instances for web colors.
+
+.. data:: IndianRed
+.. data:: LightCoral
+.. data:: Salmon
+.. data:: DarkSalmon
+.. data:: LightSalmon
+.. data:: Red
+.. data:: Crimson
+.. data:: FireBrick
+.. data:: DarkRed
+.. data:: Pink
+.. data:: LightPink
+.. data:: HotPink
+.. data:: DeepPink
+.. data:: MediumVioletRed
+.. data:: PaleVioletRed
+.. data:: LightSalmon
+.. data:: Coral
+.. data:: Tomato
+.. data:: OrangeRed
+.. data:: DarkOrange
+.. data:: Orange
+.. data:: Gold
+.. data:: Yellow
+.. data:: LightYellow
+.. data:: LemonChiffon
+.. data:: LightGoldenrodYellow
+.. data:: PapayaWhip
+.. data:: Moccasin
+.. data:: PeachPuff
+.. data:: PaleGoldenrod
+.. data:: Khaki
+.. data:: DarkKhaki
+.. data:: Lavender
+.. data:: Thistle
+.. data:: Plum
+.. data:: Violet
+.. data:: Orchid
+.. data:: Fuchsia
+.. data:: Magenta
+.. data:: MediumOrchid
+.. data:: MediumPurple
+.. data:: BlueViolet
+.. data:: DarkViolet
+.. data:: DarkOrchid
+.. data:: DarkMagenta
+.. data:: Purple
+.. data:: Indigo
+.. data:: DarkSlateBlue
+.. data:: SlateBlue
+.. data:: MediumSlateBlue
+.. data:: GreenYellow
+.. data:: Chartreuse
+.. data:: LawnGreen
+.. data:: Lime
+.. data:: LimeGreen
+.. data:: PaleGreen
+.. data:: LightGreen
+.. data:: MediumSpringGreen
+.. data:: SpringGreen
+.. data:: MediumSeaGreen
+.. data:: SeaGreen
+.. data:: ForestGreen
+.. data:: Green
+.. data:: DarkGreen
+.. data:: YellowGreen
+.. data:: OliveDrab
+.. data:: Olive
+.. data:: DarkOliveGreen
+.. data:: MediumAquamarine
+.. data:: DarkSeaGreen
+.. data:: LightSeaGreen
+.. data:: DarkCyan
+.. data:: Teal
+.. data:: Aqua
+.. data:: Cyan
+.. data:: LightCyan
+.. data:: PaleTurquoise
+.. data:: Aquamarine
+.. data:: Turquoise
+.. data:: MediumTurquoise
+.. data:: DarkTurquoise
+.. data:: CadetBlue
+.. data:: SteelBlue
+.. data:: LightSteelBlue
+.. data:: PowderBlue
+.. data:: LightBlue
+.. data:: SkyBlue
+.. data:: LightSkyBlue
+.. data:: DeepSkyBlue
+.. data:: DodgerBlue
+.. data:: CornflowerBlue
+.. data:: RoyalBlue
+.. data:: Blue
+.. data:: MediumBlue
+.. data:: DarkBlue
+.. data:: Navy
+.. data:: MidnightBlue
+.. data:: Cornsilk
+.. data:: BlanchedAlmond
+.. data:: Bisque
+.. data:: NavajoWhite
+.. data:: Wheat
+.. data:: BurlyWood
+.. data:: Tan
+.. data:: RosyBrown
+.. data:: SandyBrown
+.. data:: Goldenrod
+.. data:: DarkGoldenrod
+.. data:: Peru
+.. data:: Chocolate
+.. data:: SaddleBrown
+.. data:: Sienna
+.. data:: Brown
+.. data:: Maroon
+.. data:: White
+.. data:: Snow
+.. data:: Honeydew
+.. data:: MintCream
+.. data:: Azure
+.. data:: AliceBlue
+.. data:: GhostWhite
+.. data:: WhiteSmoke
+.. data:: Seashell
+.. data:: Beige
+.. data:: OldLace
+.. data:: FloralWhite
+.. data:: Ivory
+.. data:: AntiqueWhite
+.. data:: Linen
+.. data:: LavenderBlush
+.. data:: MistyRose
+.. data:: Gainsboro
+.. data:: LightGrey
+.. data:: Silver
+.. data:: DarkGray
+.. data:: Gray
+.. data:: DimGray
+.. data:: LightSlateGray
+.. data:: SlateGray
+.. data:: DarkSlateGray
+.. data:: Black
View
27 docs/dev/image.rst
@@ -1,27 +0,0 @@
-#####
-Image
-#####
-
-An ``Image`` object (``pymaging.image.Image``) has following required attributes:
-
-* ``width``: Width of the image in pixels
-* ``height``: Height of the image in pixels
-* ``pixels``: A list of arrays (``array.array``). Each array in the list is a
- **line** in the image. Each array is the actual image data for
- that line in the image.
-* ``mode``: The color mode (RGB/RGBA).
-* ``palette``: The palette object (a list of colors represented as lists) or
- ``None`` if the image has no palette.
-* ``pixelsize``: The size of a pixel in the array.
-
-
-About pixelsize
-===============
-
-If ``pixelsize`` is ``1`` and the ``palette`` is set, the actual values stored
-in ``pixels`` are actually indices into the ``palette``. So to get the actual
-data (color) can be fetched using ``palette[pixelvalue]``. Otherwise you can
-get the data (color) using ``pixels[y][x * pixelsize:(x * pixelsize) + pixelsize]``.
-
-There is also the helper method ``Image.get_color`` to get a color at a x/y
-position, this should only be used for very high level operation.
View
3  docs/dev/index.rst
@@ -15,8 +15,7 @@ Contents
:maxdepth: 2
/dev/setup
- /dev/overview
- /dev/image
+ /dev/api
/dev/incubator
/dev/formats
/dev/contribute
View
4 docs/dev/setup.rst
@@ -4,5 +4,5 @@ Setup for development
Clone the git repository using ``git clone https://github.com/ojii/pymaging.git``.
-To run the code, you need to be in a virtualenv that has ``distribute``
-installed. For the tests you can use ``nose`` but it is not required.
+To run the tests, simply execute ``setup.py test`` with a Python version of your choice, or run ``./runtests.sh`` to run
+it against all installed (and supported) Python versions.
View
2  pymaging/__init__.py
@@ -25,4 +25,4 @@
from pymaging.image import Image
-__version__ = '0.0.0'
+__version__ = '0.1'
View
2  pymaging/exceptions.py
@@ -27,7 +27,5 @@
class PymagingException(Exception): pass
-class ImageModeError(PymagingException): pass
-class ImageSizeMismatch(PymagingException): pass
class FormatNotSupported(PymagingException): pass
class InvalidColor(PymagingException): pass
View
5 pymaging/formats.py
@@ -60,10 +60,6 @@ def register(self, format):
for extension in format.extensions:
self.names[extension] = format
- def get_formats(self):
- self._populate()
- return self.registry
-
def get_format_objects(self):
self._populate()
return self.formats
@@ -73,7 +69,6 @@ def get_format(self, format):
return self.names.get(format, None)
registry = FormatRegistry()
-get_formats = registry.get_formats
get_format_objects = registry.get_format_objects
get_format = registry.get_format
register = registry.register
View
19 pymaging/helpers.py
@@ -23,26 +23,7 @@
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-import array
from math import ceil
-from collections import deque
-
-class Fliprow(object):
- def __init__(self, rowlength, pixelsize):
- self.indices = deque()
- indicesappend = self.indices.append
- tmp = deque()
- append = tmp.append
- pop = tmp.pop
- for i in range(rowlength - 1, -1, -1):
- append(i)
- if not i % pixelsize:
- while tmp:
- indicesappend(pop())
-
- def flip(self, row):
- return array.array('B', (row[i] for i in self.indices))
def get_transformed_dimensions(transform, box):
View
3  pymaging/image.py
@@ -27,9 +27,8 @@
from pymaging.affine import AffineTransform
from pymaging.exceptions import FormatNotSupported, InvalidColor
from pymaging.formats import get_format, get_format_objects
-from pymaging.helpers import Fliprow, get_transformed_dimensions
+from pymaging.helpers import get_transformed_dimensions
from pymaging.resample import nearest
-import array
import os
View
6 pymaging/pixelarray.py
@@ -41,12 +41,6 @@ def get(self, x, y):
start = self._translate(x, y)
return [self.data[start+i] for i in range(self.pixelsize)]
- def get_multiple(self, start_x, end_x, start_y, end_y):
- """
- Returns a list of pixels (a list of lists of length `self.pixelsize`) in the rectangle start_x/start_y-end_x/end_y
- """
- return [[self.get(x, y) for x in range(start_x, end_x)] for y in range(start_y, end_y)]
-
def set(self, x, y, pixel):
"""
Sets the pixel (a tuple of length `self.pixelsize`) to the pixel array at x/y
View
3  pymaging/resample.py
@@ -25,7 +25,7 @@
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from pymaging.pixelarray import get_pixel_array
-__all__ = ('nearest', 'bilinear')
+__all__ = ('nearest', 'bilinear', 'Resampler')
from pymaging.affine import AffineTransform
from pymaging.helpers import get_transformed_dimensions
@@ -39,7 +39,6 @@ def __init__(self):
raise NotImplementedError(
"%r is abstract, instantiate a subclass instead" % Resampler
)
- return super(Resampler, self).__init__()
def affine(self, source, transform, resize_canvas=True):
if resize_canvas:
View
7 pymaging/shapes.py
@@ -28,7 +28,12 @@
import math
-class Pixel(object):
+class BaseShape(object):
+ def iter_pixels(self, color):
+ raise StopIteration()
+
+
+class Pixel(BaseShape):
def __init__(self, x, y):
self.x = x
self.y = y
View
23 pymaging/test_utils.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+import unittest
+import array
+from pymaging.colors import ColorType
+from pymaging.image import Image
+from pymaging.pixelarray import get_pixel_array
+
+
+def image_factory(colors, alpha=True):
+ height = len(colors)
+ width = len(colors[0]) if height else 0
+ pixel_size = 4 if alpha else 3
+ pixel_array = get_pixel_array(array.array('B', [0] * width * height * pixel_size), width, height, pixel_size)
+ for y in range(height):
+ for x in range(width):
+ pixel_array.set(x, y, colors[y][x].to_pixel(pixel_size))
+ return Image(pixel_array, ColorType(pixel_size, alpha))
+
+
+class PymagingBaseTestCase(unittest.TestCase):
+ def assertImage(self, img, colors, alpha=True):
+ check = image_factory(colors, alpha)
+ self.assertEqual(img.pixels, check.pixels)
View
23 pymaging/tests/test_basic.py
@@ -23,14 +23,12 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from __future__ import absolute_import
-from pymaging.colors import Color, ColorType
+from pymaging.colors import Color
from pymaging.exceptions import FormatNotSupported
from pymaging.image import Image
-from pymaging.pixelarray import get_pixel_array
from pymaging.shapes import Line, Pixel
+from pymaging.test_utils import PymagingBaseTestCase, image_factory
from pymaging.webcolors import Red, Green, Blue, Black, White, Lime
-import array
-import unittest
try: # pragma: no-cover
# 2.x
from StringIO import StringIO
@@ -39,23 +37,6 @@
from io import StringIO
-def image_factory(colors, alpha=True):
- height = len(colors)
- width = len(colors[0]) if height else 0
- pixelsize = 4 if alpha else 3
- pixel_array = get_pixel_array(array.array('B', [0] * width * height * pixelsize), width, height, pixelsize)
- for y in range(height):
- for x in range(width):
- pixel_array.set(x, y, colors[y][x].to_pixel(pixelsize))
- return Image(pixel_array, ColorType(pixelsize, alpha))
-
-
-class PymagingBaseTestCase(unittest.TestCase):
- def assertImage(self, img, colors, alpha=True):
- check = image_factory(colors, alpha)
- self.assertEqual(img.pixels, check.pixels)
-
-
class BasicTests(PymagingBaseTestCase):
def _get_fake_image(self):
return image_factory([
View
10 runtests.sh
@@ -2,6 +2,7 @@
PYTHON_VERSIONS="2.6 2.7 3.1 3.2 3.3"
COMMAND="setup.py test"
+STATUS=0
for version in $PYTHON_VERSIONS; do
pybin="python$version"
@@ -10,6 +11,7 @@ for version in $PYTHON_VERSIONS; do
echo "Running tests for Python $version"
echo "****************************"
$pybin $COMMAND
+ STATUS=$(($STATUS+$?))
else
echo "****************************"
echo "Python $version not found, skipping"
@@ -23,4 +25,12 @@ if [ `which pypy` ]; then
echo "Running tests for PyPy $pypyversion"
echo "**************************************************"
pypy $COMMAND
+ STATUS=$(($STATUS+$?))
fi
+echo
+if [ $STATUS -eq 0 ]; then
+ echo "All versions OK"
+else
+ echo "One or more versions FAILED"
+fi
+
Please sign in to comment.
Something went wrong with that request. Please try again.