def to_render(rect, ch, rot=0): rot = to_rad(rot) rot = (-1) * rot x = rect[0] y = rect[1] try: ctx.translate(Vector(x, y)) ctx.rotate(rot) ctx.set_source_colour(Colour.grey(1)) ctx.set_font_face(qah_face) ctx.set_font_size(text_size) ctx.show_glyphs(ch) # ctx.glyph_path(ch) # ctx.stroke() ctx.rotate(-rot) ctx.translate(Vector(-x, -y)) except: ef = open('errorFile.txt', 'a') st = 'X co-ordinate ' + str(x) + ', Y co-ordinate ' + str( y) + ', Angle ' + str(rot) ef.write(st) ef.close() return art_BB(ch, x, y, rot)
def grayscale(self, grayscale): """Set self._graycale to boolean value indicating whether to format output to grayscale. If grayscale is true, set self._cairo_format as CAIRO.FORMAT_A8. Set self._canvas_color as CAIRO colour black. Set alpha value of self._text_color to 1 (no transparency). If grayscale is false, set self._cairo_format as CAIRO.FORMAT_RGB24 (24 bit RGB format). Set self._canvas_color as CAIRO colour white and text color as black.""" self._grayscale = grayscale # Configure format and color according to grayscale option if grayscale: self._cairo_format = CAIRO.FORMAT_A8 # 8 bits grayscale format self._canvas_color = Colour.grey(0, 0) # grey(i,a) => rgba(i,i,i,a) self._text_color = Colour.grey(0, 1) # Only alpha value matters else: self._cairo_format = CAIRO.FORMAT_RGB24 self._canvas_color = Colour.grey(255, 1) self._text_color = Colour.grey(0, 1)
def art_BB(ch, x, y, rot): # creating new surface here surf = qah.ImageSurface.create(format=CAIRO.FORMAT_RGB24, dimensions=fsize) cnt = qah.Context.create(surf) cnt.translate(Vector(x, y)) cnt.rotate(rot) cnt.set_source_colour(Colour.grey(1)) cnt.set_font_face(qah_face) cnt.set_font_size(text_size) cnt.show_glyphs(ch) cnt.glyph_path(ch) cnt.stroke() img = pngB_to_np(surf.to_png_bytes()) bb = boundB(img[:, :, 1]) # plt.imshow(img[:,:,1]) return bb
def test_grayscale_setter(self): # Test setter in initialization vg = VisualGenerator(grayscale=True) self.assertTrue(vg._grayscale) self.assertEqual(vg._cairo_format, CAIRO.FORMAT_A8) self.assertEqual(vg._canvas_color.r, Colour.grey(0, 0).r) self.assertEqual(vg._canvas_color.g, Colour.grey(0, 0).g) self.assertEqual(vg._canvas_color.b, Colour.grey(0, 0).b) self.assertEqual(vg._canvas_color.a, Colour.grey(0, 0).a) self.assertEqual(vg._text_color.r, Colour.grey(0, 1).r) self.assertEqual(vg._text_color.g, Colour.grey(0, 1).g) self.assertEqual(vg._text_color.b, Colour.grey(0, 1).b) self.assertEqual(vg._text_color.a, Colour.grey(0, 1).a) # Test setter after initialization vg.grayscale = False self.assertFalse(vg._grayscale) self.assertEqual(vg._cairo_format, CAIRO.FORMAT_RGB24) self.assertEqual(vg._canvas_color.r, Colour.grey(255, 1).r) self.assertEqual(vg._canvas_color.g, Colour.grey(255, 1).g) self.assertEqual(vg._canvas_color.b, Colour.grey(255, 1).b) self.assertEqual(vg._canvas_color.a, Colour.grey(255, 1).a) self.assertEqual(vg._text_color.r, Colour.grey(0, 1).r) self.assertEqual(vg._text_color.g, Colour.grey(0, 1).g) self.assertEqual(vg._text_color.b, Colour.grey(0, 1).b) self.assertEqual(vg._text_color.a, Colour.grey(0, 1).a)
def from_f0r_colour(fc) : return \ Colour(fc.r, fc.g, fc.b, 1)
.glyph_extents(glyphs) ) figure_bounds = math.ceil(glyph_extents.bounds) pix = qah.ImageSurface.create ( format = CAIRO.FORMAT_RGB24, dimensions = figure_bounds.dimensions ) # Actually render the glyphs into a Cairo context: # In[56]: (qah.Context.create(pix) .translate(- figure_bounds.topleft) .set_source_colour(Colour.grey(1)) .paint() .set_source_colour(Colour.grey(0)) .set_font_face(qah_face) .set_font_size(text_size) .show_glyphs(glyphs) ) # In[57]: pix.flush().write_to_png("b.png")
# Creating ft_face ft_face = ft.new_face(font_path) text_size = font_size # Creating Buffer buf = hb.Buffer.create() # setting char size to font face ft_face.set_char_size(size=text_size, resolution=qah.base_dpi) hb_font = hb.Font.ft_create(ft_face) qah_face = qah.FontFace.create_for_ft_face(ft_face) # In[71]: ctx = qah.Context.create(pix) # ctx.set_source_colour(Colour.grey(0)) # ctx.paint() ctx.set_source_colour(Colour.grey(1)) ctx.set_font_face(qah_face) ctx.set_font_size(text_size) # In[72]: factor = 0 y = 0 bb = [] for l in lines: l = l.split() l = " ".join(l) x = 0 # carriage-return y += line_spacing # line-feed prev_tot_wid = 1000
pix = qah.ImageSurface.create(format=CAIRO.FORMAT_RGB24, dimensions=fsize) # In[663]: # Creating ft_face ft_face = ft.new_face(font_path) text_size = font_size # Creating Buffer buf = hb.Buffer.create() # setting char size to font face ft_face.set_char_size(size=text_size, resolution=qah.base_dpi) hb_font = hb.Font.ft_create(ft_face) qah_face = qah.FontFace.create_for_ft_face(ft_face) ctx = qah.Context.create(pix) ctx.set_source_colour(Colour.grey(0)) ctx.paint() # ctx.set_source_colour(Colour.grey(1)) # ctx.set_font_face(qah_face) # ctx.set_font_size(text_size) # In[664]: l = l.strip() actual_len = len(l) word_text = glyphList(l) wl = len(word_text) # actual_len,wl # In[665]:
def render_curved(self, font, word_text): """ use curved baseline for rendering word """ wl = len(word_text) isword = len(word_text.split()) == 1 # do curved iff, the length of the word <= 10 if not isword or wl > 10 or np.random.rand() > self.p_curved: return self.render_multiline(font, word_text) # create the surface: lspace = font.get_sized_height() + 1 lbound = font.get_rect(word_text) fsize = (round(2.0 * lbound.width), round(3 * lspace)) font_path = font.path font_size = font.size space = font.get_rect('O') spaceWidth = space.width * 0.85 line_spacing = font.get_sized_height() + 1 fsize = Vector(int(fsize[0] + spaceWidth), int(fsize[1] + spaceWidth)) pix = qah.ImageSurface.create(format=CAIRO.FORMAT_RGB24, dimensions=fsize) # Creating ft_face ft_face = ft.new_face(font_path) text_size = font_size # Creating Buffer buf = hb.Buffer.create() # setting char size to font face ft_face.set_char_size(size=text_size, resolution=qah.base_dpi) hb_font = hb.Font.ft_create(ft_face) qah_face = qah.FontFace.create_for_ft_face(ft_face) ctx = qah.Context.create(pix) ctx.set_source_colour(Colour.grey(0)) ctx.paint() bbs = [] word_text = word_text.strip() word_text_len = len(word_text) ### Added on feb, 22, 2019 ## single word will be there. shiftFactor = 1.0 shiftAdditional = 0 ## Please refer to multiline for explaination. st_bound, glyph_3 = get_Bound_Glyph(word_text, buf, hb_font, ft_face, text_size) shift = shiftFactor * (st_bound.topleft)[0] + shiftAdditional x = spaceWidth * 0.7 + shift y = line_spacing * 0.8 st_bound, glyph_3 = get_Bound_Glyph(word_text, buf, hb_font, ft_face, text_size) ctx.translate(Vector(x + shift, y)) ctx.set_source_colour(Colour.grey(1)) ctx.set_font_face(qah_face) ctx.set_font_size(text_size) ctx.show_glyphs(glyph_3) img = pngB_to_np(pix.to_png_bytes()) curveIntensity = np.random.randint(-20, 20) img = transform_desire(img, curveIntensity) left, top, width, height = boundB(img[:, :, 1]) avg_w = width / word_text_len extd = 0 for i in range(word_text_len): bbs.append(np.array([left + extd, top, avg_w, height])) extd = extd + avg_w # # ### Code add end feb, 22, 2019 # # word_text = glyphList(l,line_spacing,buf,hb_font,ft_face,text_size) # # wl = len(word_text) # # # actual_len,wl # # # In[665]: # # mid_idx = wl//2 # # bsln = BaselineState() # # BS = bsln.get_sample() # # curve = [BS['curve'](i-mid_idx) for i in range(wl)] # # # some changes # # if wl <= 1: # # curve[mid_idx] = 0 # # else: # # curve[mid_idx] = -(np.sum(curve)/(wl-1)) # # # In[666]: # # rots = [-int(math.degrees(math.atan(BS['diff'](i-mid_idx)/(font_size/2)))) for i in range(wl)] # # # In[667]: # # # /rots # # # In[668]: # # rect = get_rect(word_text[mid_idx],qah_face,text_size,angle=0) # # # In[669]: # # leftx = pix.width/2 - rect.width/2 # # topx = pix.height/2 +rect.height/2 +curve[mid_idx] # # rect2 = (leftx,topx) # # rect.top = topx # # rect.left = leftx # # (rect.left,rect.top) # # # In[670]: # # # In[671]: # # mid_b = to_render(rect2, word_text[mid_idx],rots[mid_idx],ctx,fsize,qah_face,text_size) # # mid_bbs = np.array(mid_b) # # # In[672]: # # last_rect = rect # # # In[673]: # # bbs = [] # # ch_idx = [] # # for i in range(wl): # # if i == mid_idx: # # bbs.append(mid_bbs) # # ch_idx.append(i) # # continue # # if i < mid_idx: #left-chars # # i = mid_idx-1-i # # elif i==mid_idx+1: #right-chars begin # # last_rect = rect # # ch_idx.append(i) # # ch = word_text[i] # # newrect = get_rect(ch,qah_face,text_size,angle=0) # # newrect.top = last_rect.top # # if i > mid_idx: # # (newrect.left,newrect.top) = (last_rect.topleft[0]+last_rect.width+2, newrect.topleft[1]) # # else: # # (newrect.left,newrect.top) = (last_rect.topleft[0]-2-newrect.width, newrect.topleft[1]) # # newrect.top = max(newrect.height, min(fsize[1] - newrect.height, newrect.middle[1] + curve[i])) - newrect.height/2 # # try: # # bbrect = to_render((newrect.left,newrect.top),ch,rots[i],ctx,fsize,qah_face,text_size) # # except ValueError: # # bbrect = to_render((newrect.left,newrect.top), ch,0,ctx,fsize,qah_face,text_size) # # bbs.append(np.array(bbrect)) # # last_rect = newrect # # bbs_sequence_order = [] # # bbs_sequence_order = [None for i in ch_idx] # # for idx,i in enumerate(ch_idx): # # bbs_sequence_order[i] = bbs[idx] # # bbs = bbs_sequence_order # # diffCount = actual_len - wl # # bblast = bbs[wl-1] # # for faltuItr in range(diffCount): # # bbs.append(np.array([bblast[0],bblast[1],bblast[2],bblast[3]])) # # pix.flush().write_to_png('spcurved.png') # img = pngB_to_np(pix.to_png_bytes()) #dicc= {} #dicc['img'] = img[:,:,1] #dicc['bb'] = bbs #pl = open('save_curve.pkl','wb') # print("saved") #pickle.dump(dicc,pl,protocol=2) #pl.close() #f=open('save_curve.pkl','rb') #dicc = pickle.load(f) Simg1 = img[:, :, 0] # plt.imsave('croppedImage/spcurved'+str(self.jj)+'.png', Simg1) #self.jj = self.jj+1 bb = bbs bb = np.array(bb) Simg1 = Simg1.swapaxes(0, 1) # crop the surface to fit the text: # bbs = np.array(bbs) # surf_arr, bbs = crop_safe(pygame.surfarray.pixels_alpha(surf), rect_union, bb, pad=5) r0 = pygame.Rect(bb[0]) rect_union = r0.unionall(bb) surf_arr, bbs = crop_safe(Simg1, rect_union, bb, pad=5) surf_arr = surf_arr.swapaxes(0, 1) # plt.imsave('/home/jaya/abc.jpg',surf_arr) return surf_arr, word_text, bbs
def render_multiline(self, font, text): """ renders multiline TEXT on the pygame surface SURF with the font style FONT. A new line in text is denoted by \n, no other characters are escaped. Other forms of white-spaces should be converted to space. returns the updated surface, words and the character bounding boxes. """ # Adding Custom Code here by removing the Orginal Code # get the number of lines lines = text.split('\n') lengths = [len(l) for l in lines] # font parameters: line_spacing = font.get_sized_height() + 1 # initialize the surface to proper size: line_bounds = font.get_rect(lines[np.argmax(lengths)]) fsize = (round(2.0 * line_bounds.width), round(1.25 * line_spacing * len(lines))) #surf = pygame.Surface(fsize, pygame.locals.SRCALPHA, 32) space = font.get_rect('O') spaceWidth = space.width * 0.85 ## 0.8 has been multiplied here surfx, surfy = fsize font_path = font.path font_size = font.size #lines = di['lines'] fsize = Vector(int(surfx + space.width), int(surfy + line_spacing)) #line_spacing = di['line_spacing'] pix = qah.ImageSurface.create(format=CAIRO.FORMAT_RGB24, dimensions=fsize) # Creating ft_face ft_face = ft.new_face(font_path) text_size = font_size # Creating Buffer buf = hb.Buffer.create() # setting char size to font face ft_face.set_char_size(size=text_size, resolution=qah.base_dpi) # ft_face.underline = font.underline hb_font = hb.Font.ft_create(ft_face) qah_face = qah.FontFace.create_for_ft_face(ft_face) ctx = qah.Context.create(pix) # ctx.set_source_colour(Colour.grey(0)) # ctx.paint() ctx.set_source_colour(Colour.grey(1)) ctx.set_font_face(qah_face) ctx.set_font_size(text_size) # Start Replacing Code from here ## for the purpose of shifting in horizontal direction. shiftAdditional = 0 # By What factor shifting should be done shiftFactor = 1.1 factor = 0 y = 0 bb = [] ## The recent addtion code. feb 19,2019 ## Project make faster. ## No need for the word wise bounding box. So, now they can be eliminated. ''' The procedure is as follow. - Since we do not require individual character bounding box, we will discard that functionality. - We will place a word and create fake bounding box for it. - right from the top left. - width of the bounding box will be simply ((width of word)/total bounding box) ''' ## Ends here feb 19,2019 for l in lines: # picking up a line. l = l.split() l = " ".join(l) x = spaceWidth * 0.7 # carriage-return y += (line_spacing * 0.8) # line-feed words = l.split() for w in words: st_bound, glyph_3 = get_Bound_Glyph(w, buf, hb_font, ft_face, text_size) shift = shiftFactor * (st_bound.topleft)[0] + shiftAdditional ## since now we have required information for rendering. ## We know bounding box, we know glyphs, time to plot. char_in_w = len(w) avg_bounding_width = st_bound.width / char_in_w ## for each character we have to place a fake bounding box width_shift = 0 for i in range(char_in_w): ## bounding box consist of top-left point + width and height. bb.append( np.array([ x + shift + width_shift, y + (st_bound.topleft)[1], avg_bounding_width, st_bound.height ])) width_shift = width_shift + avg_bounding_width ## now since we have generated fake bounding box, ## next task will be to render glyphs on the actual surface. ## Remember context is a pen for us. ## Go to the point from where you want to write. ctx.translate(Vector(x + shift, y)) # setting the color that we wish to use. ctx.set_source_colour(Colour.grey(1)) # setting the font_face ctx.set_font_face(qah_face) # defining the size. ctx.set_font_size(text_size) # rendering the glyphs on the surface. ctx.show_glyphs(glyph_3) ## translate back to the original position. ctx.translate(Vector(-(x + shift), -y)) ## Shift the x to new position. x = x + st_bound.width + shift + spaceWidth ## resetting the shift. shift = 0 # for l in lines: # l = l.split() # l = " ".join(l) # #print(spaceWidth) # x = spaceWidth*0.7 # carriage-return # y += (line_spacing*0.8) # line-feed # prev_tot_wid = 1000 # st = '' # ln = len(l) # i = 0 # bbCount = 0 # charLen = 0 # diffCount = 0 # shift = 0 # for ch in l: # render each character # if ch.isspace(): # just shift # st_bound,glyph3 = get_Bound_Glyph(st,buf,hb_font,ft_face,text_size) # shift = shiftFactor*(st_bound.topleft)[0] + shiftAdditional # bb.append(np.array([x+shift,y+(st_bound.topleft)[1],st_bound.width,st_bound.height])) # bbCount += 1 # ctx.translate(Vector(x+shift,y)) # ctx.set_source_colour(Colour.grey(1)) # ctx.set_font_face(qah_face) # ctx.set_font_size(text_size) # ctx.show_glyphs(glyph3) # # ctx.glyph_path(glyph3) # # ctx.stroke() # ctx.translate(Vector(-(x+shift),-y)) # diffCount = charLen - bbCount # for faltuItr in range(diffCount): # bb.append(np.array([x+shift,y+(st_bound.topleft)[1],st_bound.width,st_bound.height])) # bbCount = 0 # charLen = 0 # x+= st_bound.width+shift # x += spaceWidth # st = '' # prev_tot_wid = 1000 # else: # charLen += 1 # curr_bound,glyph1 = get_Bound_Glyph(ch,buf,hb_font,ft_face,text_size) # if i == 0: # factor = curr_bound.width/3.5 # upto_bound,glyph2 = get_Bound_Glyph(st+ch,buf,hb_font,ft_face,text_size) # if (upto_bound.width)+factor < prev_tot_wid+curr_bound.width: # # st = st + ch # prev_tot_wid = upto_bound.width # shift += shiftFactor*(upto_bound.topleft)[0] + shiftAdditional # else: # st_bound,glyph3 = get_Bound_Glyph(st,buf,hb_font,ft_face,text_size) # shift += shiftFactor*(st_bound.topleft)[0] + shiftAdditional # bb.append(np.array([x+shift,y+(st_bound.topleft)[1],st_bound.width,st_bound.height])) # bbCount += 1 # ctx.translate(Vector(x+shift,y)) # ctx.set_source_colour(Colour.grey(1)) # ctx.set_font_face(qah_face) # ctx.set_font_size(text_size) # ctx.show_glyphs(glyph3) # # ctx.glyph_path(glyph3) # # ctx.stroke() # ctx.translate(Vector(-(x+shift),-y)) # x+= st_bound.width+shift # st = ch # prev_tot_wid = curr_bound.width # shift = 0 # if i == ln-1: # # shift = (st_bound.topleft)[0] # st_bound,gly5 = get_Bound_Glyph(st,buf,hb_font,ft_face,text_size) # shift = shiftFactor*(st_bound.topleft)[0] + shiftAdditional # ctx.translate(Vector(x+shift,y)) # # ctx.set_source_colour(Colour.grey(0)) # # ctx.paint() # #glyphs = get_glyphs(st) # ctx.set_source_colour(Colour.grey(1)) # ctx.set_font_face(qah_face) # ctx.set_font_size(text_size) # ctx.show_glyphs(gly5) # # ctx.glyph_path(gly5) # # ctx.stroke() # ctx.translate(Vector(-(x+shift),-y)) # bb.append(np.array([x+shift,y+(st_bound.topleft)[1],st_bound.width,st_bound.height])) # bbCount += 1 # diffCount = charLen - bbCount # for fitr in range(diffCount): # bb.append(np.array([x+shift,y+(st_bound.topleft)[1],st_bound.width,st_bound.height])) # charLen = 0 # bbCount = 0 # i += 1 ########################## Replacing of the code end here ################## ############################### img = pngB_to_np(pix.to_png_bytes()) #dicc= {} #dicc['img'] = img[:,:,1] #dicc['bb'] = bb Simg = img[:, :, 1] # self.ii = self.ii+1 #bb = dicc['bb'] bb = np.array(bb) # Simg = Simg.astype(np.uint8) # Simg = Simg[:,:,1] Simg = Simg.swapaxes(0, 1) # get the union of characters for cropping: # r0 = pygame.Rect(bbs[0]) # rect_union = r0.unionall(bbs) # Simg1 = Simg1.swapaxes(0,1) # get the words: words = ' '.join(text.split()) #bbs = np.array(bbs) # f=open('temp2.pkl','rb') # bb = pickle.load(f) # bb = np.array(bb) # crop the surface to fit the text: # bbs = np.array(bbs) r0 = pygame.Rect(bb[0]) rect_union = r0.unionall(bb) surf_arr, bbs = crop_safe(Simg, rect_union, bb, pad=5) surf_arr = surf_arr.swapaxes(0, 1) #self.visualize_bb(surf_arr,bbs) return surf_arr, words, bbs