def contrast_text(self): """Returns hex code of a color that contrasts with this one, for overlaying text. Includes the #.""" # get rgb and hsv values rgbcolor = RGBColor() rgbcolor.set_from_rgb_hex(self.color_hex) hsvcolor = rgbcolor.convert_to('hsv') new_v = hsvcolor.hsv_v; if new_v <= .55: new_v = 1.0; elif new_v > .55: new_v = 0.0; new_h = hsvcolor.hsv_h new_s = 0 contrast = HSVColor(hsv_h = new_h, hsv_s = new_s, hsv_v = new_v) contrast_rgb = contrast.convert_to('rgb') return contrast_rgb.get_rgb_hex()
def get_rgb(self): """ return the color as a list """ if not hasattr(self, '_rgb'): c = RGBColor() c.set_from_rgb_hex(self.sRGB) self._rgb = (c.rgb_r / 255.0, c.rgb_g / 255.0, c.rgb_b / 255.0) return self._rgb
def get_lab(self): """ returns the current point in L*a*b* """ if not hasattr(self, '_lab'): c = RGBColor() c.set_from_rgb_hex(self.sRGB) self._lab = c.convert_to('lab').get_value_tuple() return self._lab
def get_lab(self): """ returns the current point in L*a*b* """ if not hasattr(self, '_lab'): c = RGBColor() c.set_from_rgb_hex(self.sRGB) self._lab = c.convert_to('lab').get_value_tuple() return self._lab
def extract_bsdf(wd): color = RGBColor() color.set_from_rgb_hex(wd.color) lab = color.convert_to('lab') c = wd.contrast d = wd.d() return lab, (c, d)
def get_rgb(self): """ return the color as a list """ if not hasattr(self, '_rgb'): c = RGBColor() c.set_from_rgb_hex(self.sRGB) self._rgb = (c.rgb_r / 255.0, c.rgb_g / 255.0, c.rgb_b / 255.0) return self._rgb
def extract_bsdf(wd): color=RGBColor() color.set_from_rgb_hex(wd.color) lab=color.convert_to('lab') c=wd.contrast d=wd.d() return lab,(c,d)
def scaled_rgb(hex_color, component=None, factor=1.0): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) values = list(map(lambda x: factor * (x / 255), rgb_color.get_value_tuple())) if component is None: return '{} {} {}'.format(*rgb_color.get_value_tuple()) else: comp_idx = ('R', 'G', 'B').index(component) return '{}'.format(values[comp_idx])
def save(self, *args, **kwargs): if (self.color_L is None) or (self.color_a is None) or (self.color_b is None): c = RGBColor() c.set_from_rgb_hex(self.color) c = c.convert_to('lab') self.color_L = c.lab_l self.color_a = c.lab_a self.color_b = c.lab_b super(ShapeBsdfLabel_wd, self).save(*args, **kwargs)
def find_color_opeds(rgb_hex): 'Returns matching opeds for a given color' color = RGBColor() color.set_from_rgb_hex('#' + rgb_hex) cursor = db_find(color) colors = mongo_to_colors(cursor) results = find_closest(color, colors)[:MAX_COLOR_RESULTS] opeds = [result[0] for result in results] return opeds
def alter_lch(hex_color, value, component='L', relative=True): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) lch_color = rgb_color.convert_to('lchab') lch_lst = list(lch_color.get_value_tuple()) comp_idx = ('L', 'C', 'H').index(component) lch_lst[comp_idx] = lch_lst[comp_idx] + value if relative else value L, C, H = lch_lst lch_res = LCHabColor(L, C, H) return lch_to_hex(lch_res)
def fromRGBAHex(self, rgba_hex, background_hex): self.fromRGBHex(rgba_hex[:7]) if len(rgba_hex) > 7: opacity = int(100 * (int(rgba_hex[7:], 16) / 255)) background = RGBColor() if len(background_hex) > 7: background_hex = "#ffffff" background.set_from_rgb_hex(background_hex) self.mix(background, opacity)
def alter_lch(hex_color, value, component='L', relative=True): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) lch_color = rgb_color.convert_to('lchab') lch_lst = list(lch_color.get_value_tuple()) comp_idx = ('L', 'C', 'H').index(component) lch_lst[comp_idx] = lch_lst[comp_idx] + value if relative else value L, C, H = lch_lst lch_res = LCHabColor(L, C, H) return lch_to_hex(lch_res)
def save(self, *args, **kwargs): if (self.color_L is None) or (self.color_a is None) or (self.color_b is None): c = RGBColor() c.set_from_rgb_hex(self.color) c = c.convert_to('lab') self.color_L = c.lab_l self.color_a = c.lab_a self.color_b = c.lab_b super(ShapeBsdfLabel_wd, self).save(*args, **kwargs)
def scaled_rgb(hex_color, component=None, factor=1.0): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) values = list( map(lambda x: factor * (x / 255), rgb_color.get_value_tuple())) if component is None: return '{} {} {}'.format(*rgb_color.get_value_tuple()) else: comp_idx = ('R', 'G', 'B').index(component) return '{}'.format(values[comp_idx])
def update_shape_dominant_delta(shape, save=True): """ Update shape dominant_delta """ if not shape.dominant_rgb0 or not shape.dominant_rgb1: return c0 = RGBColor() c1 = RGBColor() c0.set_from_rgb_hex(shape.dominant_rgb0) c1.set_from_rgb_hex(shape.dominant_rgb1) shape.dominant_delta = c0.delta_e(c1) if save: shape.save()
def update_shape_dominant_delta(shape, save=True): """ Update shape dominant_delta """ if not shape.dominant_rgb0 or not shape.dominant_rgb1: return c0 = RGBColor() c1 = RGBColor() c0.set_from_rgb_hex(shape.dominant_rgb0) c1.set_from_rgb_hex(shape.dominant_rgb1) shape.dominant_delta = c0.delta_e(c1) if save: shape.save()
def handle(self, *args, **options): comparisons = [] comparisons += IntrinsicPointComparison.objects.all() \ .filter(point1_image_darker__isnull=True) \ .values_list('id', 'point1__sRGB', 'point2__sRGB') comparisons += IntrinsicPointComparisonResponse.objects.all() \ .filter(reflectance_eq=False, reflectance_dd__isnull=True) \ .order_by().distinct('comparison') \ .values_list('comparison__id', 'comparison__point1__sRGB', 'comparison__point2__sRGB') comparisons = list(set(comparisons)) for (id, sRGB1, sRGB2) in progress_bar(comparisons): c1 = RGBColor() c1.set_from_rgb_hex(sRGB1) l1 = c1.convert_to('lab').lab_l c2 = RGBColor() c2.set_from_rgb_hex(sRGB2) l2 = c2.convert_to('lab').lab_l if l1 < l2: IntrinsicPointComparison.objects \ .filter(id=id).update(point1_image_darker=True) IntrinsicPointComparisonResponse.objects \ .filter(comparison_id=id, darker="1") \ .update(reflectance_eq=False, reflectance_dd=True) IntrinsicPointComparisonResponse.objects \ .filter(comparison_id=id, darker="2") \ .update(reflectance_eq=False, reflectance_dd=False) else: IntrinsicPointComparison.objects \ .filter(id=id).update(point1_image_darker=False) IntrinsicPointComparisonResponse.objects \ .filter(comparison_id=id, darker="1") \ .update(reflectance_eq=False, reflectance_dd=False) IntrinsicPointComparisonResponse.objects \ .filter(comparison_id=id, darker="2") \ .update(reflectance_eq=False, reflectance_dd=True) IntrinsicPointComparisonResponse.objects \ .filter(comparison_id=id, darker="E") \ .update(reflectance_eq=True, reflectance_dd=None)
def set_light(self, light, hex, brightness=0, on=True): rgb = RGBColor() rgb.set_from_rgb_hex(hex) color = rgb.convert_to('hsv') bri = int(color.hsv_v * 254) hue = int(color.hsv_h * 200) sat = int(color.hsv_s * 254) if brightness > 0: bri = brightness params = { "on": on, "bri": bri, "hue": hue, "sat": sat, } params = json.dumps(params) self.send_data(light, params)
def refresh_values(self): if not self.color_hex.islower(): self.color_hex = self.color_hex.lower() # get rgb and hsv values rgbcolor = RGBColor() rgbcolor.set_from_rgb_hex(self.color_hex) hsvcolor = rgbcolor.convert_to('hsv') self.R = rgbcolor.rgb_r self.G = rgbcolor.rgb_g self.B = rgbcolor.rgb_b self.H = round(hsvcolor.hsv_h) # need to multiply by 100 to get the percent self.S = round(hsvcolor.hsv_s * 100.0) self.V = round(hsvcolor.hsv_v * 100.0) # make rounded values self.rR = round_rgb_colorvalue(self.R) self.rG = round_rgb_colorvalue(self.G) self.rB = round_rgb_colorvalue(self.B) round_rgb = RGBColor(rgb_r = self.rR, rgb_g = self.rG, rgb_b = self.rB) round_hsv = round_rgb.convert_to('hsv') self.rounded_hex = round_rgb.get_rgb_hex()[1:7] self.rH = round_hsv.hsv_h self.rS = round_hsv.hsv_s self.rV = round_hsv.hsv_v # check to see if this is a round color if self.R == self.rR and self.G == self.rG and self.B == self.rB: self.is_round = True else: self.is_round = False
def E2(shape): if shape.substance_entropy > 2.0: yield 10000.0 yield 10000.0 yield 10000.0 yield 10000.0 return color = RGBColor() color.set_from_rgb_hex(shape.dominant_rgb0) lab2 = color.convert_to('lab') yield lab.delta_e(lab2) # cie2000 delta e color.set_from_rgb_hex(shape.dominant_rgb1) lab2 = color.convert_to('lab') yield lab.delta_e(lab2) # cie2000 delta e color.set_from_rgb_hex(shape.dominant_rgb2) lab2 = color.convert_to('lab') yield lab.delta_e(lab2) # cie2000 delta e color.set_from_rgb_hex(shape.dominant_rgb3) lab2 = color.convert_to('lab') yield lab.delta_e(lab2) # cie2000 delta e
def E2(shape): if shape.substance_entropy>2.0: yield 10000.0 yield 10000.0 yield 10000.0 yield 10000.0 return color=RGBColor() color.set_from_rgb_hex(shape.dominant_rgb0) lab2=color.convert_to('lab') yield lab.delta_e(lab2) # cie2000 delta e color.set_from_rgb_hex(shape.dominant_rgb1) lab2=color.convert_to('lab') yield lab.delta_e(lab2) # cie2000 delta e color.set_from_rgb_hex(shape.dominant_rgb2) lab2=color.convert_to('lab') yield lab.delta_e(lab2) # cie2000 delta e color.set_from_rgb_hex(shape.dominant_rgb3) lab2=color.convert_to('lab') yield lab.delta_e(lab2) # cie2000 delta e
class ShapeBsdfLabel_wd(ShapeBsdfLabelBase): """ Ward BSDF model. Note: This is the "balanced" ward-duel model with energy balance at all angles from [Geisler-Moroder, D., and Dur, A. A new ward brdf model with bounded albedo. In Computer Graphics Forum (2010), vol. 29, Wiley Online Library, pp. 1391-1398.]. We use the implementation from Mitsuba available at http://www.mitsuba-renderer.org. """ shape = models.ForeignKey(MaterialShape, related_name='bsdfs_wd') # c in [0, 1] contrast = models.FloatField() # d in [0, 15] discretized alpha doi = models.IntegerField() # true if the 'rho_s only' was selected, false if traditional ward metallic = models.BooleanField(default=False) # color in "#RRGGBB" sRGB hex format color = models.CharField(max_length=7) @staticmethod def version(): return 'wd' def __unicode__(self): return 'ward sRGB=%s' % (self.color) def get_thumb_template(self): return 'bsdf_wd_shape_thumb.html' def c(self): return self.contrast def d(self): return 1 - (0.001 + (15 - self.doi) * 0.2 / 15) def d_edits(self): return json.loads(self.edit_dict)['doi'] def c_edits(self): return json.loads(self.edit_dict)['contrast'] def alpha(self): return 1 - self.d() def rho_s(self): rho_s = self.rho()[1] return '%0.3f, %0.3f, %0.3f' % rho_s def rho_d(self): rho_d = self.rho()[0] return '%0.3f, %0.3f, %0.3f' % rho_d def rho(self): if not hasattr(self, '_rho'): rgb = self.colormath_rgb() v = self.v() # approximate cielab_inverse_f. # we have V instead of L, so the same inverse formula doesn't # apply anyway. finv = v**3 if self.metallic: rho_s = finv s = rho_s / (v * 255.0) if v > 0 else 0 self._rho = ( (0, 0, 0), (s * rgb.rgb_r, s * rgb.rgb_g, s * rgb.rgb_b), ) else: rho_d = finv t = self.contrast + (rho_d * 0.5)**(1.0 / 3.0) rho_s = t**3 - rho_d * 0.5 rho_t = rho_s + rho_d if rho_t > 1: rho_s /= rho_t rho_d /= rho_t s = rho_d / (v * 255.0) if v > 0 else 0 self._rho = ((s * rgb.rgb_r, s * rgb.rgb_g, s * rgb.rgb_b), (rho_s, rho_s, rho_s)) return self._rho def v(self): """ Return the V component of HSV, in the range [0, 1] """ rgb = self.colormath_rgb() return max(rgb.rgb_r, rgb.rgb_b, rgb.rgb_g) / 255.0 def colormath_rgb(self): if not hasattr(self, '_colormath_rgb'): self._colormath_rgb = RGBColor() self._colormath_rgb.set_from_rgb_hex(self.color) return self._colormath_rgb def colormath_lab(self): if not hasattr(self, '_colormath_lab'): self._colormath_lab = self.colormath_rgb().convert_to('lab') return self._colormath_lab def color_distance(self, bsdf): return math.sqrt((self.color_L - bsdf.color_L)**2 + (self.color_a - bsdf.color_a)**2 + (self.color_b - bsdf.color_b)**2) def gloss_distance(self, bsdf): return math.sqrt((self.c() - bsdf.c())**2 + (1.78 * (self.d() - bsdf.d()))**2) def save(self, *args, **kwargs): if (self.color_L is None) or (self.color_a is None) or (self.color_b is None): c = RGBColor() c.set_from_rgb_hex(self.color) c = c.convert_to('lab') self.color_L = c.lab_l self.color_a = c.lab_a self.color_b = c.lab_b super(ShapeBsdfLabel_wd, self).save(*args, **kwargs) @staticmethod def mturk_submit(user, hit_contents, results, time_ms, time_active_ms, version, experiment, mturk_assignment=None, **kwargs): """ Add new instances from a mturk HIT after the user clicks [submit] """ if unicode(version) != u'1.0': raise ValueError("Unknown version: '%s'" % version) if not hit_contents: return {} new_objects = {} for shape in hit_contents: d = results[unicode(shape.id)] shape_time_ms = time_ms[unicode(shape.id)] shape_time_active_ms = time_active_ms[unicode(shape.id)] edit_dict = d[u'edit'] edit_sum = sum(int(edit_dict[k]) for k in edit_dict) edit_nnz = sum(int(int(edit_dict[k]) > 0) for k in edit_dict) init_method = 'KR' envmap = EnvironmentMap.objects.get( id=json.loads(experiment.variant)['envmap_id']) doi = int(d[u'doi']) contrast = float(d[u'contrast']) metallic = (int(d[u'type']) == 1) color = d['color'] give_up = d[u'give_up'] give_up_msg = d[u'give_up_msg'] bsdf, bsdf_created = shape.bsdfs_wd.get_or_create( user=user, mturk_assignment=mturk_assignment, time_ms=shape_time_ms, time_active_ms=shape_time_active_ms, doi=doi, contrast=contrast, metallic=metallic, color=color, give_up=give_up, give_up_msg=give_up_msg, edit_dict=json.dumps(edit_dict), edit_sum=edit_sum, edit_nnz=edit_nnz, envmap=envmap, init_method=init_method, ) if bsdf_created: new_objects[get_content_tuple(shape)] = [bsdf] if ((not bsdf.image_blob) and 'screenshot' in d and d['screenshot'].startswith('data:image/')): save_obj_attr_base64_image(bsdf, 'image_blob', d['screenshot']) return new_objects
def raw_rgb(hex_color): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) return '{} {} {}'.format(*rgb_color.get_value_tuple())
def hex_to_rgb(hex): color = RGBColor() color.set_from_rgb_hex(hex) return color
class ShapeBsdfLabel_wd(ShapeBsdfLabelBase): """ Ward BSDF model. Note: This is the "balanced" ward-duel model with energy balance at all angles from [Geisler-Moroder, D., and Dur, A. A new ward brdf model with bounded albedo. In Computer Graphics Forum (2010), vol. 29, Wiley Online Library, pp. 1391-1398.]. We use the implementation from Mitsuba available at http://www.mitsuba-renderer.org. """ shape = models.ForeignKey(MaterialShape, related_name='bsdfs_wd') # c in [0, 1] contrast = models.FloatField() # d in [0, 15] discretized alpha doi = models.IntegerField() # true if the 'rho_s only' was selected, false if traditional ward metallic = models.BooleanField(default=False) # color in "#RRGGBB" sRGB hex format color = models.CharField(max_length=7) @staticmethod def version(): return 'wd' def __unicode__(self): return 'ward sRGB=%s' % (self.color) def get_thumb_template(self): return 'bsdf_wd_shape_thumb.html' def c(self): return self.contrast def d(self): return 1 - (0.001 + (15 - self.doi) * 0.2 / 15) def d_edits(self): return json.loads(self.edit_dict)['doi'] def c_edits(self): return json.loads(self.edit_dict)['contrast'] def alpha(self): return 1 - self.d() def rho_s(self): rho_s = self.rho()[1] return '%0.3f, %0.3f, %0.3f' % rho_s def rho_d(self): rho_d = self.rho()[0] return '%0.3f, %0.3f, %0.3f' % rho_d def rho(self): if not hasattr(self, '_rho'): rgb = self.colormath_rgb() v = self.v() # approximate cielab_inverse_f. # we have V instead of L, so the same inverse formula doesn't # apply anyway. finv = v ** 3 if self.metallic: rho_s = finv s = rho_s / (v * 255.0) if v > 0 else 0 self._rho = ( (0, 0, 0), (s * rgb.rgb_r, s * rgb.rgb_g, s * rgb.rgb_b), ) else: rho_d = finv t = self.contrast + (rho_d * 0.5) ** (1.0 / 3.0) rho_s = t ** 3 - rho_d * 0.5 rho_t = rho_s + rho_d if rho_t > 1: rho_s /= rho_t rho_d /= rho_t s = rho_d / (v * 255.0) if v > 0 else 0 self._rho = ( (s * rgb.rgb_r, s * rgb.rgb_g, s * rgb.rgb_b), (rho_s, rho_s, rho_s) ) return self._rho def v(self): """ Return the V component of HSV, in the range [0, 1] """ rgb = self.colormath_rgb() return max(rgb.rgb_r, rgb.rgb_b, rgb.rgb_g) / 255.0 def colormath_rgb(self): if not hasattr(self, '_colormath_rgb'): self._colormath_rgb = RGBColor() self._colormath_rgb.set_from_rgb_hex(self.color) return self._colormath_rgb def colormath_lab(self): if not hasattr(self, '_colormath_lab'): self._colormath_lab = self.colormath_rgb().convert_to('lab') return self._colormath_lab def color_distance(self, bsdf): return math.sqrt((self.color_L - bsdf.color_L) ** 2 + (self.color_a - bsdf.color_a) ** 2 + (self.color_b - bsdf.color_b) ** 2) def gloss_distance(self, bsdf): return math.sqrt((self.c() - bsdf.c()) ** 2 + (1.78 * (self.d() - bsdf.d())) ** 2) def save(self, *args, **kwargs): if (self.color_L is None) or (self.color_a is None) or (self.color_b is None): c = RGBColor() c.set_from_rgb_hex(self.color) c = c.convert_to('lab') self.color_L = c.lab_l self.color_a = c.lab_a self.color_b = c.lab_b super(ShapeBsdfLabel_wd, self).save(*args, **kwargs) @staticmethod def mturk_submit(user, hit_contents, results, time_ms, time_active_ms, version, experiment, mturk_assignment=None, **kwargs): """ Add new instances from a mturk HIT after the user clicks [submit] """ if unicode(version) != u'1.0': raise ValueError("Unknown version: '%s'" % version) if not hit_contents: return {} new_objects = {} for shape in hit_contents: d = results[unicode(shape.id)] shape_time_ms = time_ms[unicode(shape.id)] shape_time_active_ms = time_active_ms[unicode(shape.id)] edit_dict = d[u'edit'] edit_sum = sum(int(edit_dict[k]) for k in edit_dict) edit_nnz = sum(int(int(edit_dict[k]) > 0) for k in edit_dict) init_method = 'KR' envmap = EnvironmentMap.objects.get( id=json.loads(experiment.variant)['envmap_id']) doi = int(d[u'doi']) contrast = float(d[u'contrast']) metallic = (int(d[u'type']) == 1) color = d['color'] give_up = d[u'give_up'] give_up_msg = d[u'give_up_msg'] bsdf, bsdf_created = shape.bsdfs_wd.get_or_create( user=user, mturk_assignment=mturk_assignment, time_ms=shape_time_ms, time_active_ms=shape_time_active_ms, doi=doi, contrast=contrast, metallic=metallic, color=color, give_up=give_up, give_up_msg=give_up_msg, edit_dict=json.dumps(edit_dict), edit_sum=edit_sum, edit_nnz=edit_nnz, envmap=envmap, init_method=init_method, ) if bsdf_created: new_objects[get_content_tuple(shape)] = [bsdf] if ((not bsdf.image_blob) and 'screenshot' in d and d['screenshot'].startswith('data:image/')): save_obj_attr_base64_image(bsdf, 'image_blob', d['screenshot']) return new_objects
def hex_to_lch(hex_color): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) return rgb_color.convert_to('lchab')
def fromRGBHex(self, rgb_hex): rgb = RGBColor() rgb.set_from_rgb_hex(rgb_hex) self._fromRGBColor(rgb)
def hex_to_lch(hex_color): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) return rgb_color.convert_to('lchab')
def raw_rgb(hex_color): rgb_color = RGBColor() rgb_color.set_from_rgb_hex(hex_color) return '{} {} {}'.format(*rgb_color.get_value_tuple())