TL;DR
with golang
Source code: https://gist.github.com/tng527/484d77db0b86ff6c7aa13435073e1100
When I posted the LGTM image of the picked up item at the time of the review, I was pleased as follows.
Isn't the motivation of the members exploding by always using fresh LGTM images? (hypothesis)
Many of the LGTM images I picked up are uninteresting (personal impressions), so I decided to generate them.
As usual, it's just a code to move in time for ad-care. Error handling is not basic, and usability improvements will be made as needed in the future.
Be sure to check the copyright of the image before compositing, as it may violate the copyright. (I will not attach images in this article)
We compared services that provide several GIF images and selected GIPHY, which provides APIs and provides many GIFs with comical movements.
I referred to the following site.
Official GIPHY API documentation: https://developers.giphy.com/docs/api/endpoint#trending
Japanese article on how to use the GIPHY API: https://qiita.com/onetk/items/5244a359958bb22f7bb6
Roughly like this. You don't have to specify offset ...
Set the environment variable to the API Key issued by GIPHY with GIPHY_KEY
as the key.
type ImageInfo struct {
Url string
Title string
}
const getLimit = 50
func getGifUrl(keyword string) []ImageInfo {
url := "https://api.giphy.com/v1/gifs/search"
req, _ := http.NewRequest("GET", url, nil)
params := req.URL.Query()
params.Add("api_key", os.Getenv("GIPHY_KEY"))
params.Add("q", keyword)
params.Add("limit", fmt.Sprint(getLimit))
req.URL.RawQuery = params.Encode()
client := new(http.Client)
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var j interface{}
json.Unmarshal(body, &j)
var imgs []ImageInfo
for i := 0; i < getLimit; i++ { // TODO:Turn by the number of values taken instead of getLimit
url, _ := jsonpointer.Get(j, "/data/"+fmt.Sprint(i)+"/images/original/url")
title, _ := jsonpointer.Get(j, "/data/"+fmt.Sprint(i)+"/title")
img := ImageInfo{Url: url.(string), Title: title.(string)}
imgs = append(imgs, img)
}
return imgs
}
I've almost done this implementation. Thank you very much. https://qiita.com/yyoshiki41/items/37010dd281bfd29731cc
func download(info ImageInfo) error {
resp, err := http.Get(info.Url)
if err != nil {
return err
}
defer resp.Body.Close()
file, err := os.Create(path.Join("raw", info.Title+".gif"))
if err != nil {
return err
}
_, err = io.Copy(file, resp.Body)
if closeErr := file.Close(); err == nil {
err = closeErr
}
return err
}
Almost follow this. (Paku is just ...) https://qiita.com/syamaoka/items/a85e360970a8111a1dac
This is a little tricky, and the font size is automatically (appropriately) adjusted to match the size of the original image. I couldn't find any options such as centering, so I had some difficulty in aligning. The font size must be specified in points, but the alignment must be described in pixels (xt-like). It seems that if you multiply the point by 1.333, it will be a pixel, so when I adopted it, it seems that it works almost well.
func combineLGTM(filename string) {
f, err := os.Open(path.Join("raw", filename))
if err != nil {
panic(err)
}
defer f.Close()
g, err := gif.DecodeAll(f)
if err != nil {
panic(err)
}
lgtmImage, err := generateLGTMImage(g.Image[0])
if err != nil {
panic(err)
}
var images []*image.Paletted
var delays []int
var disposals []byte
for i, img := range g.Image {
logoRectangle := image.Rectangle{image.Point{0, 0}, lgtmImage.Bounds().Size()}
draw.Draw(img, logoRectangle, lgtmImage, image.Point{0, 0}, draw.Over)
images = append(images, img)
delays = append(delays, g.Delay[i])
disposals = append(disposals, gif.DisposalNone)
}
buf := new(bytes.Buffer)
if err = gif.EncodeAll(buf, &gif.GIF{
Image: images,
Delay: delays,
Disposal: disposals,
BackgroundIndex: g.BackgroundIndex,
Config: g.Config,
}); err != nil {
panic(err)
}
file, err := os.Create(path.Join("lgtm", filename))
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer file.Close()
file.Write(buf.Bytes())
}
func generateLGTMImage(img *image.Paletted) (image.Image, error) {
//Generate img to fit gif size
newImg := image.NewRGBA(img.Rect)
tt, err := truetype.Parse(gobold.TTF)
if err != nil {
return nil, err
}
log.Println(newImg.Rect.Dx())
//Correct pixel to point, secure a place for 4 characters, and have some margin on the left and right(0.8 times)To have
fontsize := float64(newImg.Rect.Dx()) * 0.25 * 0.8 / 1.333
d := &font.Drawer{
Dst: newImg,
Src: image.NewUniform(color.White),
Face: truetype.NewFace(tt, &truetype.Options{
Size: fontsize,
},
),
//In the horizontal direction, the font size is converted to pixels for 2 characters.
Dot: fixed.Point26_6{fixed.Int26_6(((float64(newImg.Rect.Dx()) / 2) - fontsize*2/1.333) * 64), fixed.Int26_6((newImg.Rect.Dy() - 20) * 64)},
}
d.DrawString("LGTM")
return newImg, nil
}
--Depending on the background color, the white characters of "LGTM" are difficult to see, so I want to border them. ――Due to the movement of the original image, the edges of the letters "LGTM" are strangely blackened, so I want to do something about it ... --I want to define offset and loop around (currently, I can only get 50 offset: 0)
I noticed after making it, but I already had a tool ... https://m0t0k1ch1st0ry.com/blog/2015/03/14/lgtmize/