Пример #1
0
def image(request, path, token, autogen=False):

    is_admin = False
    if ("is_admin=true" in token and request and request.user.has_perm('admin')) or autogen:
        parameters = token
        is_admin = True
        if autogen:
            token = image_create_token(parameters)
    else:
        parameters = request.session.get(token, token)

    path = os.path.normcase(path)
    
    cached_image_path = settings.IMAGE_CACHE_ROOT + "/" + path + "/"
    cached_image_file = cached_image_path + token

    response = HttpResponse()
    response['Content-type'] = 'image/jpeg'
    response['Expires'] = 'Fri, 09 Dec 2327 08:34:31 GMT'
    response['Last-Modified'] = 'Fri, 24 Sep 2010 11:36:29 GMT'
    response.status_code = 200
    
    # If we already have the cache we send it instead of recreating it
    if os.path.exists(smart_unicode(cached_image_file)):
        
        if autogen:
            return 'Already generated'
        
        f = open(cached_image_file, "r")
        response.write(f.read())
        f.close()

        return response
    
    if parameters == token and not is_admin:
        return HttpResponse("Forbidden", status=403)

    qs = QueryDict(parameters)

    ROOT_DIR = settings.MEDIA_ROOT
    try:
        if qs['static'] == "true":
            ROOT_DIR = settings.STATIC_ROOT
    except KeyError:
        pass

    format = qs.get('format', IMAGE_DEFAULT_FORMAT)
    quality = int(qs.get('quality', IMAGE_DEFAULT_QUALITY))
    mask = qs.get('mask', None)

    if mask is not None:
        format = "PNG"

    fill = qs.get('fill', None)
    background = qs.get('background', None)
    tint = qs.get('tint', None)

    center = qs.get('center', ".5,.5")
    mode = qs.get('mode', "crop")
        
    overlays = qs.getlist('overlay')
    overlay_sources = qs.getlist('overlay_source')
    overlay_tints = qs.getlist('overlay_tint')

    width = int(qs.get('width', None))
    height = int(qs.get('height', None))

    if "video" in qs:
        data, http_response = generate_thumb(ROOT_DIR + "/" + smart_unicode(path), width=width, height=height)
        response.status_code = http_response
    else:
        try:
            try:
                f = urllib.urlopen(qs['url'])
                data = f.read()
                f.close()
            except KeyError:
                f = open(ROOT_DIR + "/" + smart_unicode(path), 'r')
                data = f.read()
                f.close()
        except IOError:
            response.status_code = 404
            data = image_text(IMAGE_ERROR_NOT_FOUND, width, height)

    try:
        if mode == "scale":
            output_data = scale(data, width, height, overlays=overlays, overlay_sources=overlay_sources, overlay_tints=overlay_tints, mask=mask, format=format, quality=quality, fill=fill, background=background, tint=tint)
        else:
            output_data = scaleAndCrop(data, width, height, True, overlays=overlays, overlay_sources=overlay_sources, overlay_tints=overlay_tints, mask=mask, center=center, format=format, quality=quality, fill=fill, background=background, tint=tint)
    except IOError:
        response.status_code = 500
        output_data = image_text(IMAGE_ERROR_NOT_VALID, width, height)

    if response.status_code == 200:
        if not os.path.exists(cached_image_path):
            os.makedirs(cached_image_path)
    
        f = open(cached_image_file, "w")
        f.write(output_data)
        f.close()
        if autogen:
            return 'Generated ' + str(response.status_code)
    else:
        if autogen:
            return 'Failed ' + cached_image_file
    
    response.write(output_data)

    return response
Пример #2
0
def generate_thumb(video_path, thumb_size=None, format='jpg', frames=100, width=100, height=100):
    histogram = []

    http_status = 200
    
    name = video_path
    path = video_path

    if not os.path.exists(video_path):
        return image_text(IMAGE_ERROR_VIDEO_NOT_FOUND, width, height), '404'

    framemask = "%s%s%s%s" % (settings.FILE_UPLOAD_TEMP_DIR,
                              name.split('/')[-1].split('.')[0] + str(time.time()),
                              '.%d.',
                              format)
    # ffmpeg command for grabbing N number of frames
    cmd = "/usr/bin/ffmpeg -y -t 00:00:05 -i '%s' '%s'" % (path, framemask)

    # make sure that this command worked or return.
    if os.system(cmd) != 0:
        return image_text(IMAGE_ERROR_FFMPEG, width, height), '500'

    # loop through the generated images, open, and generate the image histogram.
    for i in range(1, frames + 1):
        fname = framemask % i

        if not os.path.exists(fname):
            break

        image = Image.open(fname)

        # Convert to RGB if necessary
        if image.mode not in ('L', 'RGB'):
            image = image.convert('RGB')

        # The list of image historgrams
        histogram.append(image.histogram())

    n = len(histogram)
    avg = []

    # Get the image average of the first image
    for c in range(len(histogram[0])):
        ac = 0.0
        for i in range(n):
            ac = ac + (float(histogram[i][c]) / n)
        avg.append(ac)

    minn = -1
    minRMSE = -1

    # Compute the mean squared error
    for i in range(1, n + 1):
        results = 0.0
        num = len(avg)

        for j in range(num):
            median_error = avg[j] - float(histogram[i - 1][j])
            results += (median_error * median_error) / num
        rmse = math.sqrt(results)

        if minn == -1 or rmse < minRMSE:
            minn = i
            minRMSE = rmse

    file_location = framemask % (minn)
    image = Image.open(file_location)

    # If you want to generate a square thumbnail
    if not thumb_size is None:
        thumb_w, thumb_h = thumb_size

        if thumb_w == thumb_h:
            # quad
            xsize, ysize = image.size
            # get minimum size
            minsize = min(xsize, ysize)
            # largest square possible in the image
            xnewsize = (xsize - minsize) / 2
            ynewsize = (ysize - minsize) / 2
            # crop it
            image2 = image.crop((xnewsize, ynewsize, xsize - xnewsize, ysize - ynewsize))
            # load is necessary after crop
            image2.load()
            # thumbnail of the cropped image (with ANTIALIAS to make it look better)
            image2.thumbnail(thumb_size, Image.ANTIALIAS)
        else:
            # not quad
            image2 = image
            image2.thumbnail(thumb_size, Image.ANTIALIAS)
    else:
        image2 = image

    io = cStringIO.StringIO()

    # PNG and GIF are the same, JPG is JPEG
    if format.upper() == 'JPG':
        format = 'JPEG'

    image2.save(io, format)

    # We don't know how many frames we capture. We just captured the first 5 seconds, so keep removing until not found
    for i in range(1, 9999):
        fname = framemask % i
        try:
            os.unlink(fname)
        except OSError:
            break

    return io.getvalue(), http_status