def generate_thumbs(self, permissive=False): # "Imports" Image = self.field.db_field.rel.to Thumb = Image._meta.get_field("thumbs").rel.to has_existing_image = self.related_object is not None if not has_existing_image: ct_kwargs = {} if 'for_concrete_model' in inspect.getargspec(ContentType.objects.get_for_model).args: ct_kwargs['for_concrete_model'] = False obj_ct = ContentType.objects.get_for_model(self.instance, **ct_kwargs) image = Image(**{ 'content_type': obj_ct, 'object_id': self.instance.pk, 'field_identifier': self.field.generic_field.field_identifier, 'width': self.width, 'height': self.height, 'image': self.name, }) image.save() self.related_object = image for size in self.sizes: try: crop_thumb = self.related_object.thumbs.get(name=size.name) except Thumb.DoesNotExist: crop_thumb = self._get_new_crop_thumb(size) thumbs = self.related_object.save_size(size, thumb=crop_thumb, permissive=permissive) for slug, thumb in six.iteritems(thumbs): thumb.image = self.related_object thumb.save()
def get_for_size(self, size_slug='original'): from cropduster.models import Image image = Image.get_file_for_size(self, size_slug) if size_slug == 'preview': if not default_storage.exists(image.name): Image.save_preview_file(self, preview_w=self.preview_width, preview_h=self.preview_height) return image
def get_crop(image, crop_name, **kwargs): """ Get the crop of an image. Usage: {% get_crop article.image 'square_thumbnail' attribution=1 as img %} will assign to `img` a dictionary that looks like: { "url": '/media/path/to/my.jpg', "width": 150, "height" 150, "attribution": 'Stock Photoz', "attribution_link": 'http://stockphotoz.com', "caption": 'Woman laughing alone with salad.', "alt_text": 'Woman laughing alone with salad.' } For use in an image tag or style block like: <img src="{{ img.url }}"> The `exact_size` kwarg is deprecated. Omitting the `attribution` kwarg will omit the attribution, attribution_link, and caption. """ if "exact_size" in kwargs: warnings.warn("get_crop's `exact_size` kwarg is deprecated.", DeprecationWarning) if not image or not image.related_object: return None url = getattr(Image.get_file_for_size(image, crop_name), 'url', None) thumbs = {thumb.name: thumb for thumb in image.related_object.thumbs.all()} try: thumb = thumbs[crop_name] except KeyError: if crop_name == "original": thumb = image.related_object else: return None cache_buster = str(time.mktime(thumb.date_modified.timetuple()))[:-2] return { "url": "%s?%s" % (url, cache_buster), "width": thumb.width, "height": thumb.height, "attribution": image.related_object.attribution, "attribution_link": image.related_object.attribution_link, "caption": image.related_object.caption, "alt_text": image.related_object.alt_text, }
def upload(request): size_set = SizeSet.objects.get(id=request.GET["size_set"]) # Get the current aspect ratio if "aspect_ratio_id" in request.POST: aspect_ratio_id = int(request.POST["aspect_ratio_id"]) else: aspect_ratio_id = 0 if "image_id" in request.GET: image = CropDusterImage.objects.get(id=request.GET["image_id"]) elif "image_id" in request.POST: image = CropDusterImage.objects.get(id=request.POST["image_id"]) else: image = CropDusterImage(size_set=size_set) size = Size.objects.get_size_by_ratio(size_set.id, aspect_ratio_id) or Size() # Get the current crop try: crop = Crop.objects.get(image=image.id, size=size.id) except Crop.DoesNotExist: crop = Crop() crop.crop_w = size.width crop.crop_h = size.height crop.crop_x = 0 crop.crop_y = 0 crop.image = image crop.size = size if request.method == "POST": if request.FILES: # Process uploaded image form formset = ImageForm(request.POST, request.FILES, instance=image) if formset.is_valid(): image = formset.save() crop.image = image crop_formset = CropForm(instance=crop) else: # Invalid upload return form errors = formset.errors.values()[0] context = { "aspect_ratio_id": 0, "errors": errors, "formset": formset, "image_element_id" : request.GET["image_element_id"] } context = RequestContext(request, context) return render_to_response("admin/upload.html", context) else: #If its the first frame, get the image formset and save it (for attribution) if aspect_ratio_id ==0: formset = ImageForm(request.POST, instance=image) if formset.is_valid(): formset.save() else: formset = ImageForm(instance=image) # If there's no cropping to be done, then just complete the process if size.id: # Lets save the crop request.POST['size'] = size.id request.POST['image'] = image.id crop_formset = CropForm(request.POST, instance=crop) if crop_formset.is_valid(): crop = crop_formset.save() #Now get the next crop if it exists aspect_ratio_id = aspect_ratio_id + 1 size = Size.objects.get_size_by_ratio(size_set, aspect_ratio_id) # If there's another crop if size: try: crop = Crop.objects.get(image=image.id, size=size.id) crop_formset = CropForm(instance=crop) except Crop.DoesNotExist: crop = Crop() crop.crop_w = size.width crop.crop_h = size.height crop.crop_x = 0 crop.crop_y = 0 crop.size = size crop_formset = CropForm() # Nothing being posted, get the image and form if they exist else: formset = ImageForm(instance=image) crop_formset = CropForm(instance=crop) # If theres more cropping to be done or its the first frame, # show the upload/crop form if (size and size.id) or request.method != "POST": crop_w = crop.crop_w or size.width crop_h = crop.crop_h or size.height # Combine errors from both forms, eliminate duplicates errors = dict(crop_formset.errors) errors.update(formset.errors) all_errors = [] for error in errors.items(): all_errors.append(u"%s: %s" % (error[0].capitalize(), error[1].as_text())) context = { "aspect_ratio": size.aspect_ratio, "aspect_ratio_id": aspect_ratio_id, "browser_width": BROWSER_WIDTH, "crop_formset": crop_formset, "crop_w" : crop_w, "crop_h" : crop_h, "crop_x" : crop.crop_x or 0, "crop_y" : crop.crop_y or 0, "errors" : all_errors, "formset": formset, "image": image, "image_element_id" : request.GET["image_element_id"], "image_exists": image.image and os.path.exists(image.image.path), "min_w" : size.width, "min_h" : size.height, } context = RequestContext(request, context) return render_to_response("admin/upload.html", context) # No more cropping to be done, close out else : image_thumbs = [image.thumbnail_url(size.slug) for size in image.size_set.get_size_by_ratio()] context = { "image": image, "image_thumbs": image_thumbs, "image_element_id" : request.GET["image_element_id"] } context = RequestContext(request, context) return render_to_response("admin/complete.html", context)
def get_crop(image, crop_name, exact_size=False, **kwargs): """ Get the crop of an image. Usage: {% get_crop article.image 'square_thumbnail' attribution=1 exact_size=1 as img %} will assign to `img` a dictionary that looks like: { "url": '/media/path/to/my.jpg', "width": 150, "height" 150, "attribution": 'Stock Photoz', "attribution_link": 'http://stockphotoz.com', "caption": 'Woman laughing alone with salad.', } For use in an image tag or style block like: <img src="{{ img.url }}"> The `size` kwarg is deprecated. Omitting the `attribution` kwarg will omit the attribution, attribution_link, and caption. Omitting the `exact_size` kwarg will return the width and/or the height of the crop size that was passed in. Crop sizes do not always require both values so `exact_size` gives you access to the actual size of an image. """ if not image: return if "size" in kwargs: warnings.warn("The size kwarg is deprecated.", DeprecationWarning) data = {} data['url'] = getattr(Image.get_file_for_size(image, crop_name), 'url', None) if not exact_size: sizes = Size.flatten(image.sizes) try: size = six.next(size_obj for size_obj in sizes if size_obj.name == crop_name) except StopIteration: pass else: if size.width: data['width'] = size.width if size.height: data['height'] = size.height elif image.related_object: thumbs = {thumb.name: thumb for thumb in image.related_object.thumbs.all()} try: thumb = thumbs[crop_name] except KeyError: if crop_name == "original": thumb = image.related_object else: return None cache_buster = base64.b32encode(str(time.mktime(thumb.date_modified.timetuple()))) data.update({ "url": "%s?%s" % (data["url"], cache_buster), "width": thumb.width, "height": thumb.height, "attribution": image.related_object.attribution, "attribution_link": image.related_object.attribution_link, "caption": image.related_object.caption, }) return data
def upload(request): size_set = SizeSet.objects.get(id=request.GET["size_set"]) # Get the current aspect ratio if "aspect_ratio_id" in request.POST: aspect_ratio_id = int(request.POST["aspect_ratio_id"]) else: aspect_ratio_id = 0 image_id = None if "image_id" in request.GET: image_id = request.GET["image_id"] elif "image_id" in request.POST: image_id = request.POST["image_id"] try: image_id = int(image_id) image = CropDusterImage.objects.get(id=image_id) except: image = CropDusterImage(size_set=size_set) size = Size.objects.get_size_by_ratio(size_set.id, aspect_ratio_id) or Size() # Get the current crop try: crop = Crop.objects.get(image=image.id, size=size.id) except Crop.DoesNotExist: crop = Crop() crop.crop_w = size.width crop.crop_h = size.height crop.crop_x = 0 crop.crop_y = 0 crop.image = image crop.size = size if request.method == "POST": if request.FILES: # Process uploaded image form formset = ImageForm(request.POST, request.FILES, instance=image) if formset.is_valid(): if CROPDUSTER_EXIF_DATA: # Check for exif data and use it to populate caption/attribution try: exif_data = process_file(io.BytesIO(b"%s" % formset.cleaned_data["image"].file.getvalue())) except AttributeError: exif_data = {} if not formset.cleaned_data["caption"] and "Image ImageDescription" in exif_data: formset.data["caption"] = exif_data["Image ImageDescription"].__str__() if not formset.cleaned_data["attribution"] and "EXIF UserComment" in exif_data: formset.data["attribution"] = exif_data["EXIF UserComment"].__str__() image = formset.save() crop.image = image crop_formset = CropForm(instance=crop) else: # Invalid upload return form errors = formset.errors.values()[0] context = { "aspect_ratio_id": 0, "errors": errors, "formset": formset, "image_element_id" : request.GET["image_element_id"], "static_url": settings.STATIC_URL, } context = RequestContext(request, context) return render_to_response("admin/upload.html", context) else: #If its the first frame, get the image formset and save it (for attribution) if not aspect_ratio_id: formset = ImageForm(request.POST, instance=image) if formset.is_valid(): formset.save() else: formset = ImageForm(instance=image) # If there's no cropping to be done, then just complete the process if size.id: # Lets save the crop request.POST['size'] = size.id request.POST['image'] = image.id crop_formset = CropForm(request.POST, instance=crop) if crop_formset.is_valid(): crop = crop_formset.save() #Now get the next crop if it exists aspect_ratio_id = aspect_ratio_id + 1 size = Size.objects.get_size_by_ratio(size_set, aspect_ratio_id) # If there's another crop if size: try: crop = Crop.objects.get(image=image.id, size=size.id) crop_formset = CropForm(instance=crop) except Crop.DoesNotExist: crop = Crop() crop.crop_w = size.width crop.crop_h = size.height crop.crop_x = 0 crop.crop_y = 0 crop.size = size crop_formset = CropForm() # Nothing being posted, get the image and form if they exist else: formset = ImageForm(instance=image) crop_formset = CropForm(instance=crop) # If theres more cropping to be done or its the first frame, # show the upload/crop form if (size and size.id) or request.method != "POST": crop_w = crop.crop_w or size.width crop_h = crop.crop_h or size.height # Combine errors from both forms, eliminate duplicates errors = dict(crop_formset.errors) errors.update(formset.errors) all_errors = [] for error in errors.items(): if error[0] != '__all__': string = u"%s: %s" % (error[0].capitalize(), error[1].as_text()) else: string = error[1].as_text() all_errors.append(string) context = { "aspect_ratio": size.aspect_ratio, "aspect_ratio_id": aspect_ratio_id, "browser_width": BROWSER_WIDTH, "crop_formset": crop_formset, "crop_w" : crop_w, "crop_h" : crop_h, "crop_x" : crop.crop_x or 0, "crop_y" : crop.crop_y or 0, "errors" : all_errors, "formset": formset, "image": image, "image_element_id" : request.GET["image_element_id"], "image_exists": image.image and os.path.exists(image.image.path), "min_w" : size.width, "min_h" : size.height, "static_url": settings.STATIC_URL, } context = RequestContext(request, context) return render_to_response("admin/upload.html", context) # No more cropping to be done, close out else : image_thumbs = [image.thumbnail_url(size.slug) for size in image.size_set.get_unique_ratios()] context = { "image": image, "image_thumbs": image_thumbs, "image_element_id" : request.GET["image_element_id"], "static_url": settings.STATIC_URL, } context = RequestContext(request, context) return render_to_response("admin/complete.html", context)
def upload(request): size_set = SizeSet.objects.get(id=request.GET["size_set"]) # Get the current aspect ratio if "aspect_ratio_id" in request.POST: aspect_ratio_id = int(request.POST["aspect_ratio_id"]) else: aspect_ratio_id = 0 image_id = None if "image_id" in request.GET: image_id = request.GET["image_id"] elif "image_id" in request.POST: image_id = request.POST["image_id"] try: image_id = int(image_id) image = CropDusterImage.objects.get(id=image_id) except: image = CropDusterImage(size_set=size_set) size = Size.objects.get_size_by_ratio(size_set.id, aspect_ratio_id) or Size() # Get the current crop try: crop = Crop.objects.get(image=image.id, size=size.id) except Crop.DoesNotExist: crop = Crop() crop.crop_w = size.width crop.crop_h = size.height crop.crop_x = 0 crop.crop_y = 0 crop.image = image crop.size = size if request.method == "POST": if request.FILES: # Process uploaded image form formset = ImageForm(request.POST, request.FILES, instance=image) if formset.is_valid(): if CROPDUSTER_EXIF_DATA: # Check for exif data and use it to populate caption/attribution try: exif_data = process_file( io.BytesIO( b"%s" % formset.cleaned_data["image"].file.getvalue())) except AttributeError: exif_data = {} if not formset.cleaned_data[ "caption"] and "Image ImageDescription" in exif_data: formset.data["caption"] = exif_data[ "Image ImageDescription"].__str__() if not formset.cleaned_data[ "attribution"] and "EXIF UserComment" in exif_data: formset.data["attribution"] = exif_data[ "EXIF UserComment"].__str__() image = formset.save() crop.image = image crop_formset = CropForm(instance=crop) else: # Invalid upload return form errors = formset.errors.values()[0] context = { "aspect_ratio_id": 0, "errors": errors, "formset": formset, "image_element_id": request.GET["image_element_id"], "static_url": settings.STATIC_URL, } context = RequestContext(request, context) return render_to_response("admin/upload.html", context) else: #If its the first frame, get the image formset and save it (for attribution) if not aspect_ratio_id: formset = ImageForm(request.POST, instance=image) if formset.is_valid(): formset.save() else: formset = ImageForm(instance=image) # If there's no cropping to be done, then just complete the process if size.id: # Lets save the crop request.POST['size'] = size.id request.POST['image'] = image.id crop_formset = CropForm(request.POST, instance=crop) if crop_formset.is_valid(): crop = crop_formset.save() #Now get the next crop if it exists aspect_ratio_id = aspect_ratio_id + 1 size = Size.objects.get_size_by_ratio( size_set, aspect_ratio_id) # If there's another crop if size: try: crop = Crop.objects.get(image=image.id, size=size.id) crop_formset = CropForm(instance=crop) except Crop.DoesNotExist: crop = Crop() crop.crop_w = size.width crop.crop_h = size.height crop.crop_x = 0 crop.crop_y = 0 crop.size = size crop_formset = CropForm() # Nothing being posted, get the image and form if they exist else: formset = ImageForm(instance=image) crop_formset = CropForm(instance=crop) # If theres more cropping to be done or its the first frame, # show the upload/crop form if (size and size.id) or request.method != "POST": crop_w = crop.crop_w or size.width crop_h = crop.crop_h or size.height # Combine errors from both forms, eliminate duplicates errors = dict(crop_formset.errors) errors.update(formset.errors) all_errors = [] for error in errors.items(): if error[0] != '__all__': string = u"%s: %s" % (error[0].capitalize(), error[1].as_text()) else: string = error[1].as_text() all_errors.append(string) context = { "aspect_ratio": size.aspect_ratio, "aspect_ratio_id": aspect_ratio_id, "browser_width": BROWSER_WIDTH, "crop_formset": crop_formset, "crop_w": crop_w, "crop_h": crop_h, "crop_x": crop.crop_x or 0, "crop_y": crop.crop_y or 0, "errors": all_errors, "formset": formset, "image": image, "image_element_id": request.GET["image_element_id"], "image_exists": image.image and os.path.exists(image.image.path), "min_w": size.width, "min_h": size.height, "static_url": settings.STATIC_URL, } context = RequestContext(request, context) return render_to_response("admin/upload.html", context) # No more cropping to be done, close out else: image_thumbs = [ image.thumbnail_url(size.slug) for size in image.size_set.get_unique_ratios() ] context = { "image": image, "image_thumbs": image_thumbs, "image_element_id": request.GET["image_element_id"], "static_url": settings.STATIC_URL, } context = RequestContext(request, context) return render_to_response("admin/complete.html", context)