B
    \_;                 @   s  d dl Z d dlZd dlmZ d dlZddlmZmZ ddl	m
Z
 ddlmZ ddlmZmZ ddlmZ d dlZd d	lmZ ejZed
d eeD Zede f eZdd Zdd Zdd Zdd Zdd ZG dd deZ G dd deZ!e"dkrd dl#Z#e#$  dS )    N)
namedtuple   )ioimg_as_ubyte)resize)
color_dict)file_or_url_contextis_url)ImageCollection)requestc             c   s(   | ] \}}|t d d |D fV  qdS )c             s   s   | ]}t d | d V  qdS )   g      ?N)int).0c r   5lib/python3.7/site-packages/skimage/novice/_novice.py	<genexpr>   s    z<genexpr>.<genexpr>N)tuple)r   namergbr   r   r   r      s   r   colorsc             C   s   t | S )z0Return Picture object from the given image path.)Picture)pathr   r   r   open   s    r   c             C   s   t | trt| dks$td| tdd | D r:| S t| } x4t| D ](\}}t |trLt	||d  | |< }qLW t| S )z5Raise error if picture index is not a 2D index/slice.r   zExpected 2D index but got {0!r}c             s   s   | ]}t |tV  qd S )N)
isinstancer   )r   ir   r   r   r   !   s    z(_verify_picture_index.<locals>.<genexpr>   )
r   r   len
IndexErrorformatalllist	enumerater   slice)indexr   Z	dim_slicer   r   r   _verify_picture_index   s    
r%   c             C   s   t | dS )z.Return RGB array with first 2 axes transposed.)r   r   r   )npZ	transpose)arrayr   r   r   rgb_transpose/   s    r(   c             C   s   t | ddd S )z@Return view of image transformed from array to Cartesian origin.N)r(   )imager   r   r   array_to_xy_origin4   s    r+   c             C   s   t | dddddf S )z@Return view of image transformed from Cartesian to array origin.Nr)   )r(   )r*   r   r   r   xy_to_array_origin9   s    r,   c               @   s   e Zd ZdZd$ddZedd Zedd Zed	d
 Zej	dd
 Zedd Z
e
j	dd Z
edd Zej	dd Zedd Zej	dd Zedd Zej	dd Zedd Zej	dd Zdd Zdd Zdd  Zd!d" Zd#S )%Pixela  A single pixel in a Picture.

    Attributes
    ----------
    pic : Picture
        The Picture object that this pixel references.
    array : array_like
        Byte array with raw image data (RGB).
    x : int
        Horizontal coordinate of this pixel (left = 0).
    y : int
        Vertical coordinate of this pixel (bottom = 0).
    rgb : tuple
        RGB tuple with red, green, and blue components (0-255)
    alpha : int
        Transparency component (0-255), 255 (opaque) by default

    r   c             C   sR   || _ || _|| _| |d | _| |d | _| |d | _| || _d S )Nr   r   r   )_picture_x_y	_validate_red_green_blue_alpha)selfZpicr'   xyr   alphar   r   r   __init__R   s    zPixel.__init__c             C   s   | j S )z@Horizontal location of this pixel in the parent image(left = 0).)r/   )r6   r   r   r   r7   [   s    zPixel.xc             C   s   | j S )zAVertical location of this pixel in the parent image (bottom = 0).)r0   )r6   r   r   r   r8   `   s    zPixel.yc             C   s   | j S )z'The red component of the pixel (0-255).)r2   )r6   r   r   r   rede   s    z	Pixel.redc             C   s   |  || _|   d S )N)r1   r2   	_setpixel)r6   valuer   r   r   r;   j   s    c             C   s   | j S )z)The green component of the pixel (0-255).)r3   )r6   r   r   r   greeno   s    zPixel.greenc             C   s   |  || _|   d S )N)r1   r3   r<   )r6   r=   r   r   r   r>   t   s    c             C   s   | j S )z(The blue component of the pixel (0-255).)r4   )r6   r   r   r   bluey   s    z
Pixel.bluec             C   s   |  || _|   d S )N)r1   r4   r<   )r6   r=   r   r   r   r?   ~   s    c             C   s   | j S )z0The transparency component of the pixel (0-255).)r5   )r6   r   r   r   r9      s    zPixel.alphac             C   s   |  || _|   d S )N)r1   r5   r<   )r6   r=   r   r   r   r9      s    c             C   s   | j | j| jfS )z7The RGB color components of the pixel (3 values 0-255).)r;   r>   r?   )r6   r   r   r   r      s    z	Pixel.rgbc                sD   t |dkr| _n, fdd|D \ _ _ _d _   d S )N   c             3   s   | ]}  |V  qd S )N)r1   )r   v)r6   r   r   r      s    zPixel.rgb.<locals>.<genexpr>r   )r   rgbar2   r3   r4   r5   r<   )r6   r=   r   )r6   r   r      s
    c             C   s   | j | j| j| jfS )zYThe RGB color and transparency components of the pixel
        (4 values 0-255).
        )r;   r>   r?   r9   )r6   r   r   r   rB      s    z
Pixel.rgbac                s.    fdd|D \ _  _ _ _   d S )Nc             3   s   | ]}  |V  qd S )N)r1   )r   rA   )r6   r   r   r      s    zPixel.rgba.<locals>.<genexpr>)r2   r3   r4   r5   r<   )r6   r=   r   )r6   r   rB      s    "c             C   sN   y"t |}|dk s|dkr t W n& tk
rH   d}t||Y nX |S )z-Verifies that the pixel value is in [0, 255].r   r   z;Expected an integer between 0 and 255, but got {0} instead!)r   
ValueErrorr   )r6   r=   msgr   r   r   r1      s    
zPixel._validatec             C   s$   | j | jj| j| jf< | j  d S )N)rB   r.   xy_arrayr/   r0   _array_modified)r6   r   r   r   r<      s    zPixel._setpixelc             C   s   t |tr| j|jkS d S )N)r   r-   rB   )r6   otherr   r   r   __eq__   s    
zPixel.__eq__c             C   s   | j | j| j| jf}dj| S )Nz.Pixel(red={0}, green={1}, blue={2}, alpha={3}))r;   r>   r?   r9   r   )r6   argsr   r   r   __repr__   s    zPixel.__repr__N)r   )__name__
__module____qualname____doc__r:   propertyr7   r8   r;   setterr>   r?   r9   r   rB   r1   r<   rH   rJ   r   r   r   r   r-   >   s(   
	
r-   c               @   s  e Zd ZdZdOddZedPddZedd	 Zej	d
d	 Zedd Z
e
j	dd Z
dd Zdd Zedd Zedd Zdd Zedd Zedd Zej	dd Zedd Zej	dd Zed d! Zej	d"d! Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zed-d. Zej	d/d. Zed0d1 Zej	d2d1 Zed3d4 Zej	d5d4 Zed6d7 Zej	d8d7 Zed9d: Zej	d;d: Zed<d= Zej	d>d= Zd?d@ ZdAdB Z dCdD Z!dEdF Z"dGdH Z#dIdJ Z$dKdL Z%dMdN Z&dS )Qr   a  A 2-D picture made up of pixels.

    Attributes
    ----------
    path : str
        Path to an image file to load / URL of an image
    array : array
        Raw RGB or RGBA image data [0-255], with origin at top-left.
    xy_array : array
        Raw RGB or RGBA image data [0-255], with origin at bottom-left.

    Examples
    --------
    Load an image from a file:

    >>> from skimage import novice
    >>> from skimage import data
    >>> picture = novice.open(data.data_dir + '/chelsea.png')

    Load an image from a URL (the URL must start with ``http(s)://`` or
    ``ftp(s)://``):

    >>> picture = novice.open('https://scikit-image.org/_static/img/logo.png')  # doctest: +SKIP

    Create a blank 100 pixel wide, 200 pixel tall white image:

    >>> pic = Picture.from_size((100, 200), color=(255, 255, 255))

    Use numpy to make an RGB byte array (shape is height x width x 3):

    >>> import numpy as np
    >>> data = np.zeros(shape=(200, 100, 3), dtype=np.uint8)
    >>> data[:, :, 0] = 255  # Set red component to maximum
    >>> pic = Picture(array=data)

    Get the bottom-left pixel:

    >>> pic[0, 0]
    Pixel(red=255, green=0, blue=0, alpha=255)

    Get the top row of the picture:

    >>> pic[:, pic.height-1]
    Picture(100 x 1)

    Set the bottom-left pixel to black:

    >>> pic[0, 0] = (0, 0, 0)

    Set the top row to red:

    >>> pic[:, pic.height-1] = (255, 0, 0)

    Nc          	   C   s   d| _ d | _d | _tdd |||gD }|dkr@d}t| nr|d k	rt|s\tj|}|| _t	|"}t
t|| _t|| _W d Q R X n|d k	r|| _n|d k	r|| _| jjd dkrtj| jddd	d
| _d S )NFc             S   s   g | ]}|d k	r|qS )Nr   )r   ar   r   r   
<listcomp>   s    z$Picture.__init__.<locals>.<listcomp>r   z:Must provide a single keyword arg (path, array, xy_array).r)      r   r   )valuesaxis)	_modified_path_formatr   rC   r	   osr   abspathr   r   r   Zimreadr'   imghdrwhatrE   shaper&   insert)r6   r   r'   rE   Zn_argsrD   contextr   r   r   r:      s(    

zPicture.__init__blackc             C   st   t |tjrt| }t| t|f }tj|tjd}tj	|tjd| }|j
d dkrjtj|dddd}t|dS )aJ  Return a Picture of the specified size and a uniform color.

        Parameters
        ----------
        size : tuple
            Width and height of the picture in pixels.
        color : tuple or str
            RGB or RGBA tuple with the fill color for the picture [0-255] or
            a valid key in `color_dict`.
        )Zdtyper)   rS   r   r   )rT   rU   )r'   )r   sixZstring_typesr   r   r   r&   r'   uint8Zonesr]   r^   r   )sizecolorZrgb_sizer'   r   r   r   	from_size  s    zPicture.from_sizec             C   s   | j S )z!Image data stored as numpy array.)_array)r6   r   r   r   r'   ,  s    zPicture.arrayc             C   s*   | tj| _t| j| _| j | _d S )N)astyper&   rb   rf   r+   	_xy_arraycopy_array_backup)r6   r'   r   r   r   r'   1  s    c             C   s   | j S )z@Image data stored as numpy array with origin at the bottom-left.)rh   )r6   r   r   r   rE   7  s    zPicture.xy_arrayc             C   s   || _ t|| _d S )N)rh   r,   rf   )r6   r'   r   r   r   rE   <  s    c             C   sz   | j jdkrH| j jd dkrHtj|d  dkrH| j dddf | _ t|| j  d| _	tj
|| _t|| _dS )zSaves the picture to the given path.

        Parameters
        ----------
        path : str
            Path (with file extension) where the picture is saved.
        rS   r)   r@   )z.jpgz.jpeg.NF)r'   ndimr]   rY   r   splitextlowerr   imsaverV   rZ   rW   r[   r\   rX   )r6   r   r   r   r   saveA  s    zPicture.savec             C   s   | j | _dS )zDReset image to its original state, removing modifications.

        N)rj   r'   )r6   r   r   r   resetQ  s    zPicture.resetc             C   s   | j S )zThe path to the picture.)rW   )r6   r   r   r   r   W  s    zPicture.pathc             C   s   | j S )z True if the picture has changed.)rV   )r6   r   r   r   modified\  s    zPicture.modifiedc             C   s   d| _ d | _d S )NT)rV   rW   )r6   r   r   r   rF   a  s    zPicture._array_modifiedc             C   s   | j S )z The image format of the picture.)rX   )r6   r   r   r   r   e  s    zPicture.formatc             C   s   | j jdd S )z(The size (width, height) of the picture.Nr   )rE   r]   )r6   r   r   r   rc   j  s    zPicture.sizec             C   sd   |d | j ks|d | jkr`t|d t|d f}t| j|ddddd}|tj| _|   d S )Nr   r   TZconstantF)orderZpreserve_rangemodeZanti_aliasing)	widthheightr   r   r'   rg   r&   rb   rF   )r6   r=   Znew_sizeZ	new_arrayr   r   r   rc   o  s    
c             C   s
   | j d S )zThe width of the picture.r   )rc   )r6   r   r   r   rt   |  s    zPicture.widthc             C   s   || j f| _d S )N)ru   rc   )r6   r=   r   r   r   rt     s    c             C   s
   | j d S )zThe height of the picture.r   )rc   )r6   r   r   r   ru     s    zPicture.heightc             C   s   | j |f| _d S )N)rt   rc   )r6   r=   r   r   r   ru     s    c             C   s   t | j t   dS )zDisplay the image.N)r   Zimshowr'   show)r6   r   r   r   rv     s    zPicture.showc                s:   | j | jg tddg fddd}t  t  dS )z,Compare the image to its unmodified version.r   r   c                s    |  S )Nr   )r7   )imagesr   r   <lambda>  s    z!Picture.compare.<locals>.<lambda>)Z	load_funcN)rj   r'   r
   r   Zimshow_collectionrv   )r6   Zicr   )rw   r   compare  s    
zPicture.comparec             C   s    | j ||f }t| | j|||S )z0Create a Pixel object for a given x, y location.)rE   r-   r'   )r6   r7   r8   r   r   r   r   
_makepixel  s    zPicture._makepixelc             C   s   | j dddd|f S )z<Return a specific dimension out of the raw image data slice.N)rf   )r6   channelr   r   r   _get_channel  s    zPicture._get_channelc             C   s   || j dddd|f< dS )z5Set a specific dimension in the raw image data slice.N)rf   )r6   r{   r=   r   r   r   _set_channel  s    zPicture._set_channelc             C   s   |  d S )z'The red component of the pixel (0-255).r   )r|   ravel)r6   r   r   r   r;     s    zPicture.redc             C   s   |  d| d S )Nr   )r}   )r6   r=   r   r   r   r;     s    c             C   s   |  d S )z)The green component of the pixel (0-255).r   )r|   r~   )r6   r   r   r   r>     s    zPicture.greenc             C   s   |  d| d S )Nr   )r}   )r6   r=   r   r   r   r>     s    c             C   s   |  d S )z(The blue component of the pixel (0-255).r   )r|   r~   )r6   r   r   r   r?     s    zPicture.bluec             C   s   |  d| d S )Nr   )r}   )r6   r=   r   r   r   r?     s    c             C   s   |  d S )z0The transparency component of the pixel (0-255).rS   )r|   r~   )r6   r   r   r   r9     s    zPicture.alphac             C   s   |  d| d S )NrS   )r}   )r6   r=   r   r   r   r9     s    c             C   s   | j ddddddf S )z7The RGB color components of the pixel (3 values 0-255).NrS   )rE   )r6   r   r   r   r     s    zPicture.rgbc             C   s    || j d d d d d df< d S )NrS   )rE   )r6   r=   r   r   r   r     s    c             C   s   | j S )z8The RGBA color components of the pixel (4 values 0-255).)rE   )r6   r   r   r   rB     s    zPicture.rgbac             C   s   || j d d < d S )N)rE   )r6   r=   r   r   r   rB     s    c             c   s:   x4t | jD ]&}x t | jD ]}| ||V  qW qW dS )z&Iterates over all pixels in the image.N)rangert   ru   rz   )r6   r7   r8   r   r   r   __iter__  s    zPicture.__iter__c             C   s8   t |}tdd |D r$| j| S t| j| dS dS )z6Return `Picture`s for slices and `Pixel`s for indexes.c             s   s   | ]}t |tV  qd S )N)r   r   )r   r$   r   r   r   r     s    z&Picture.__getitem__.<locals>.<genexpr>)rE   N)r%   r    rz   r   rE   )r6   xy_indexr   r   r   __getitem__  s    
zPicture.__getitem__c             C   sJ   t |}t|tr|| | _n t|tr6|j| j|< ntd|   d S )NzInvalid value type)r%   r   r   r   r   rE   	TypeErrorrF   )r6   r   r=   r   r   r   __setitem__  s    

zPicture.__setitem__c             C   s"   t |tst t| j|jkS )N)r   r   NotImplementedErrorr&   r    r'   )r6   rG   r   r   r   rH     s    
zPicture.__eq__c             C   s   dj | j S )NzPicture({0} x {1}))r   rc   )r6   r   r   r   rJ     s    zPicture.__repr__c             C   s
   |  dS )NZpng)_repr_image_format)r6   r   r   r   
_repr_png_  s    zPicture._repr_png_c             C   s
   |  dS )NZjpeg)r   )r6   r   r   r   _repr_jpeg_   s    zPicture._repr_jpeg_c             C   s.   t  }tj|| j|d | }|  |S )N)
format_str)ra   BytesIOr   rn   r'   getvalueclose)r6   r   Z
str_bufferZ
return_strr   r   r   r     s
    zPicture._repr_image_format)NNN)r`   )'rK   rL   rM   rN   r:   staticmethodre   rO   r'   rP   rE   ro   rp   r   rq   rF   r   rc   rt   ru   rv   ry   rz   r|   r}   r;   r>   r?   r9   r   rB   r   r   r   rH   rJ   r   r   r   r   r   r   r   r      sZ   6

r   __main__)%rY   r[   collectionsr   Znumpyr&    r   r   Z	transformr   rd   r   Zio.utilr   r	   Zio.collectionr
   ra   Zsix.moves.urllibr   ZurlopendictZ	iteritemskeysr   r   r%   r(   r+   r,   objectr-   r   rK   ZdoctestZtestmodr   r   r   r   <module>   s6      J
