ios - How to convert Text into Emoji? -
i have plan convert text emoji. but, don't know how start. here screen shots looking for.
i have idea in mind achieve above result should save dictionary each character question how dictionary save emoji according character structure.
i suggest using simple bitmap technique. in first step build black , white bitmap written text in same dimensions have final image.
in second step "divide" image raster e.g. 20% smaller final emoji character create overlapping effect.
in each raster rectangle calculate black pixels. there percentage between 0-100% black pixels. if percentage e.g on 40%, random emoji placed @ center of rectangle.
you can improve effect adding small amount of random displacement.
final thoughts
i implemented , worked great. improve image further small optimization:
- for each rectangle >40% black, divide rectangle 4 zones (top left, top right, bottom left, bottom right).
- if 1 of zones has black pixel in it, count zone 1 otherwise 0.
- this creates 16 different patterns. few of these patterns move displace emoji more center of rectangle.
for example if 1000
, move top left. if 1010
left.
example code
the following example code demonstrates shown approach, without tweaks in "final thought" section. written in swift cocoa application. see application delegate of simple application provides text field , image view in main window.
you can complete application adding text field , image view main window , bind values outlets textfield
, imageview
. have bind text field value parametertext
property.
the output of application looks this:
@nsapplicationmain class appdelegate: nsobject, nsapplicationdelegate { @iboutlet weak var window: nswindow! @iboutlet weak var textfield: nstextfield! @iboutlet weak var imageview: nsimageview! var updatetimer: nstimer = nstimer() let canvassize = cgsize(width: 1024, height: 768) let canvaspadding: cgfloat = 32.0 let emojisize = 20.0 let emojiset: [nsstring] = ["🌸","🌺","🌼","🍑"] let emojijitter = 4.0 var parametertext: nsstring = "hello!" { didset { triggerimageupdate() } } func applicationdidfinishlaunching(anotification: nsnotification) { triggerimageupdate() } func applicationwillterminate(anotification: nsnotification) { } func triggerimageupdate() { updatetimer.invalidate() updatetimer = nstimer.scheduledtimerwithtimeinterval(0.5, target: self, selector: selector("updateimage"), userinfo: nil, repeats: false); } func updateimage() { imageview.image = createemojiimage(parametertext, size: canvassize, padding: canvaspadding) } // function creates simple bitmap given text. text // centered in bitmap , scaled maximum size. func createtextimage(text: nsstring, size: cgsize, padding: cgfloat) -> nsimage { let canvasrect = cgrect(x: 0.0, y: 0.0, width: size.width, height: size.height) let textrect = cgrectinset(canvasrect, padding, padding) var textbitmap = nsimage(size: size) textbitmap.lockfocus() nscolor.whitecolor().setfill() nsrectfill(canvasrect) let textfont = nsfont(name: "helvetica bold", size: 100) var textattributes: [nsobject: anyobject] = [ nsfontattributename: textfont!, nsforegroundcolorattributename: nscolor.blackcolor()] let textsize = text.sizewithattributes(textattributes); let scalewidth = textrect.size.width/textsize.width let scaleheight = textrect.size.height/textsize.height let scale: cgfloat if (scalewidth < scaleheight) { scale = scalewidth } else { scale = scaleheight } let scaledcanvassize = cgsize(width: size.width/scale, height: size.height/scale) let offset = cgpoint(x: (scaledcanvassize.width - textsize.width)/2.0, y: (scaledcanvassize.height - textsize.height)/2.0) cgcontextscalectm(nsgraphicscontext.currentcontext()!.cgcontext, scale, scale) text.drawatpoint(offset, withattributes: textattributes) textbitmap.unlockfocus() return textbitmap } func createtextbitmap(text: nsstring, size: cgsize, padding: cgfloat) -> nsbitmapimagerep { let textimage = createtextimage(text, size: size, padding: padding) let tiffimagedata = textimage.tiffrepresentation return nsbitmapimagerep(data: tiffimagedata!)! } // class represents single field. class field { let center: cgpoint let black: double init(center: cgpoint, black: double) { self.center = center self.black = black } } // function black value rectangle in image. func blackvalue(image: nsbitmapimagerep, rect: cgrect) -> double { let pixelinrect = int(rect.size.width * rect.size.height) var blackcount = 0; (var x = 0; x < int(rect.size.width); ++x) { (var y = 0; y < int(rect.size.height); ++y) { var color = image.coloratx(int(rect.origin.x), y: int(rect.origin.y))! if (color.redcomponent < 0.1) { blackcount++ } } } return double(blackcount) / double(pixelinrect) } // function rasterize bitmap single fields. func rasterizebitmap(image: nsbitmapimagerep, size: cgfloat) -> (width: int, fields: [field]) { let width = int(image.size.width/size) let height = int(image.size.height/size) var fields = [field]() (var x = 0; x < width; ++x) { (var y = 0; y < height; ++y) { let rect = cgrect(x: cgfloat(x) * size, y: cgfloat(y) * size, width: size, height: size) let center = cgpoint(x: floor(cgfloat(x) * size + size/2.0), y: image.size.height - floor(cgfloat(y) * size + size/2.0)) let black = blackvalue(image, rect: rect) var field = field(center: center, black: black) fields.append(field) } } return (width, fields) } // function create emoji image. func createemojiimage(text: nsstring, size: cgsize, padding: cgfloat) -> nsimage { // create , rasterize bitmap. let textbitmap = self.createtextbitmap(text, size: size, padding: padding) let (fieldswidth, fields) = self.rasterizebitmap(textbitmap, size: cgfloat(emojisize*0.75)) // create new image var result = nsimage(size: size) result.lockfocus() nscolor.whitecolor().setfill() let canvasrect = cgrect(x: 0.0, y: 0.0, width: size.width, height: size.height) nsrectfill(canvasrect) let textfont = nsfont(name: "apple color emoji", size: cgfloat(self.emojisize)) var textattributes: [nsobject: anyobject] = [nsfontattributename: textfont!] nscolor.blackcolor().setfill() field in fields { let jitterx = cgfloat(double(arc4random_uniform(101))/100.0*self.emojijitter-self.emojijitter/2.0) let jittery = cgfloat(double(arc4random_uniform(101))/100.0*self.emojijitter-self.emojijitter/2.0) if field.black > 0.4 { var randomemoji = self.emojiset[int(arc4random_uniform(uint32(self.emojiset.count)))] var drawingpoint = cgpoint(x: field.center.x - cgfloat(self.emojisize/2.0) + jitterx, y: field.center.y - cgfloat(self.emojisize/2.0) + jittery) randomemoji.drawatpoint(drawingpoint, withattributes: textattributes) } } result.unlockfocus() return result } }