Пример #1
0
// Scale will scale the image to the size provided.
// Note that this will destroy the current pixmap associated with this image.
// After scaling, XSurfaceSet will need to be called for each window that
// this image is painted to. (And obviously, XDraw and XPaint will need to
// be called again.)
func (im *Image) Scale(width, height int) *Image {
	dimg := New(im.X, image.Rect(0, 0, width, height))
	graphics.Scale(dimg, im)
	im.Destroy()

	return dimg
}
Пример #2
0
// Smart crop given image file & write it to io.Writer
func smartCrop(w io.Writer, r io.Reader, size []int) error {
	img, mimetype, err := image.Decode(r)
	if size == nil || err != nil {
		io.Copy(w, r)
		return nil
	}

	size = setMaxSize(fitToActualSize(&img, size))
	crop, err := smartcrop.SmartCrop(&img, size[0], size[1])
	if err != nil {
		io.Copy(w, r)
		return nil
	}

	croppedBuffer := image.NewRGBA(image.Rect(0, 0, crop.Width, crop.Height))
	draw.Draw(
		croppedBuffer,
		croppedBuffer.Bounds(),
		img,
		image.Point{crop.X, crop.Y},
		draw.Src,
	)

	dst := image.NewRGBA(image.Rect(0, 0, size[0], size[1]))
	graphics.Scale(dst, croppedBuffer)
	return writeByMimetype(w, dst, mimetype)
}
Пример #3
0
//缩放图片,proportion为比例
func reszieImage(imageName string, minWidth float32, minHeight float32) {
	src, err := LoadImage(imageName)
	if err != nil {
		log.Fatal(err)
	}

	info := src.Bounds()
	width := info.Dx()  //图片宽度
	height := info.Dy() //图片高度
	var (
		newWidth, newHeight float32
	)

	if float32(width)/float32(height) > minWidth/minHeight {
		newHeight = minHeight
		newWidth = float32(width) * minHeight / float32(height)
	} else {
		newWidth = minWidth
		newHeight = (float32(height) * minWidth) / float32(width)
	}

	// 缩略图的大小
	dst := image.NewRGBA(image.Rect(0, 0, int(newWidth), int(newHeight)))

	// 产生缩略图,等比例缩放
	err = graphics.Scale(dst, src)
	if err != nil {
		log.Fatal(err)
	}

	// 需要保存的文件
	imgcounter := 734
	saveImage(fmt.Sprintf("%03d.jpg", imgcounter), dst)
}
Пример #4
0
func ResizeWidth(img image.Image, width int) (image.Image, error) {
	s := img.Bounds().Size()
	h := int((float32(width) / float32(s.X)) * float32(s.Y))
	r := image.NewRGBA(image.Rect(0, 0, width, h))

	if err := graphics.Scale(r, img); err != nil {
		return nil, err
	}
	return r, nil
}
Пример #5
0
func load_likelost_img(json_str string) (err error) {
	//load json obj
	obj, err := JsonToLikeLostChild(json_str)
	//con
	sig_con.FontSize = 11.5
	sig_bd.FontSize = 11.5
	color_con := image.NewUniform(color.NRGBA{88, 88, 88, 255})
	//find time

	img_ft_l, err = sig_bd.GetSimpalImage("发现时间:", color_con, 2, 2)
	//describe
	img_desc_l, err = sig_bd.GetSimpalImage("特征描述:", color_con, 2, 2)
	//find address
	img_fa_l, err = sig_bd.GetSimpalImage("发现地点:", color_con, 2, 2)
	//find time right
	img_ft_r, err = sig_con.GetMoreLineImage(obj.FindTime, color_con, 304, 2, 2)
	img_desc_r, err = sig_con.GetMoreLineImage(obj.Describe, color_con, 304, 2, 2)
	img_fa_r, err = sig_con.GetMoreLineImage(obj.FindAddress, color_con, 304, 2, 2)
	//map
	gpsx := strconv.FormatFloat(obj.FindGPSX, 'f', -1, 64)
	//gpsx_off := strconv.FormatFloat(obj.FindGPSX-0.03, 'f', -1, 64)
	//gpsy_off := strconv.FormatFloat(obj.FindGPSY-0.005, 'f', -1, 64)
	gpsy := strconv.FormatFloat(obj.FindGPSY, 'f', -1, 64)
	add := obj.FindAddress
	if len(obj.FindAddress) > 16 {
		add_rune := []rune(obj.FindAddress)
		add = string(add_rune[0:12]) + "..."
	}

	map_url := "http://api.map.baidu.com/staticimage?center=" +
		gpsx + "," + gpsy + "&width=414&height=222&zoom=13&copyright=1" +
		"&labels=" + gpsx + "," + gpsy + "&labelStyles=" + url.QueryEscape(add) +
		",1,14,0x585858,0xffffff,0"
	baidu_map, err = GetImg(map_url)
	m_x, m_y := align(baidu_map.Bounds(), masker_img.Bounds())
	img_baidu_map = image.NewNRGBA(baidu_map.Bounds())
	draw.Draw(img_baidu_map, baidu_map.Bounds(), baidu_map, image.ZP, draw.Over)
	//masker_img, err = GetStaticImg("mask")
	draw.Draw(img_baidu_map, offset(baidu_map.Bounds(), m_x, m_y-20), masker_img, image.ZP, draw.Over)
	//child pic list
	length := len(obj.PicList)
	imglist = make([]image.Image, length, length)
	for i, chilpic := range obj.PicList {
		img_src, err_childlist := GetImg(chilpic.PicUrl)
		err = err_childlist
		bound := img_src.Bounds()
		dx := bound.Dx()
		dy := bound.Dy()
		dst := image.NewRGBA(image.Rect(0, 0, 414, 414*dy/dx))
		err = graphics.Scale(dst, img_src)
		imglist[i] = dst
	}
	return
}
Пример #6
0
func (xdg *XDG) scaleIcon(srcImg image.Image, name string, size int) image.Image {
	img := image.NewRGBA(image.Rect(0, 0, size, size))

	err := graphics.Scale(img, srcImg)
	if err != nil {
		fmt.Printf("Failed to scale: %s\n", err.Error())
		return nil
	}

	xdg.icons[Icon{name, size}] = img

	return img
}
Пример #7
0
func (en *JKEncoderImage) JK_reducejpeg(save, name string, enType draw.Op, quality int) error {
	// 1. Open file
	ifile, err := os.Open(name)
	if err != nil {
		return err
	}
	defer ifile.Close()

	// Create file to save
	ofile, err := os.Create(save)
	if err != nil {
		return err
	}
	defer ofile.Close()
	/*
		config, err := jpeg.DecodeConfig(ifile)
		if err != nil {
			jklog.L().Errorln("error : ", err)
		}
		jklog.L().Infof("[%d, %d]\n", config.Width, config.Height)
	*/
	img, err := jpeg.Decode(ifile)
	if err != nil {
		jklog.L().Errorln("error : ", err)
		return err
	}
	bounds := img.Bounds()

	x := bounds.Dx()
	y := bounds.Dy()
	nx := x * en.Scale / 100
	ny := y * en.Scale / 100
	m := image.NewRGBA(image.Rect(0, 0, x, y))
	jklog.L().Infof("[%d, %d] \n", x, y)
	// white := color.RGBA{255, 255, 255, 255}
	// draw.Draw(m, bounds, &image.Uniform{white}, image.ZP, draw.Src)
	// draw.Draw(m, bounds, img, image.ZP, draw.Src)
	draw.Draw(m, m.Bounds(), img, bounds.Min, enType)

	mm := image.NewRGBA(image.Rect(0, 0, nx, ny))
	graphics.Scale(mm, m)

	err = jpeg.Encode(ofile, mm, &jpeg.Options{quality})
	if err != nil {
		jklog.L().Errorln("error: ", err)
		return err
	}
	return nil
}
Пример #8
0
func main() {
	defer Recovery()

	X, Xerr = xgbutil.Dial("")
	if Xerr != nil {
		panic(Xerr)
	}

	simg, err := xgraphics.LoadPngFromFile("openbox.png")
	if err != nil {
		fmt.Println(err)
	}

	img := image.NewRGBA(image.Rect(0, 0, 50, 101))
	graphics.Scale(img, simg)

	dest := xgraphics.BlendBg(img, nil, 100, color.RGBA{255, 255, 255, 255})

	win := xgraphics.CreateImageWindow(X, dest, 3940, 400)
	X.Conn().MapWindow(win)

	time.Sleep(20 * time.Second)
}
Пример #9
0
func main() {
	flag.Parse()
	args := flag.Args()

	if flag.NArg() != 4 {
		errMsg("Usage: scale-png src-png new_width new_height dest-png")
	}

	pngsrc := args[0]
	pngdest := args[3]
	neww, errw := strconv.Atoi(args[1])
	newh, errh := strconv.Atoi(args[2])
	if errw != nil || errh != nil {
		errMsg("Could not convert (%s, %s) to integers.", args[1], args[2])
	}

	fmt.Printf("Resizing %s to (%d, %d) and saving as %s\n",
		pngsrc, neww, newh, pngdest)

	srcReader, err := os.Open(pngsrc)
	if err != nil {
		errMsg("%s is not readable.", pngsrc)
	}

	srcImg, err := png.Decode(srcReader)
	if err != nil {
		errMsg("Could not decode %s.", pngsrc)
	}

	destWriter, err := os.Create(pngdest)
	if err != nil {
		errMsg("Could not write %s", pngdest)
	}

	destImg := image.NewRGBA(image.Rect(0, 0, neww, newh))
	graphics.Scale(destImg, srcImg)

	// for x := 0; x < destImg.Bounds().Max.X; x++ {
	// for y := 0; y < destImg.Bounds().Max.Y; y++ {
	// c := destImg.At(x, y).(color.RGBA)
	// blah := 0.3 * 0xff
	// c.A = uint8(blah)
	// destImg.SetRGBA(x, y, c)
	// }
	// }

	// finalDest := image.NewRGBA(image.Rect(0, 0, neww, newh))
	// blue := color.RGBA{255, 255, 255, 255}
	// draw.Draw(finalDest, finalDest.Bounds(), image.NewUniform(blue),
	// image.ZP, draw.Src)

	// Create a transparency mask
	mask := image.NewUniform(color.Alpha16{32767})

	// Now blend our scaled image
	draw.DrawMask(destImg, destImg.Bounds(), destImg, image.ZP, mask,
		image.ZP, draw.Src)

	png.Encode(destWriter, destImg)

	fmt.Printf("Type of src: %T\n", srcImg)
	fmt.Printf("Source opaque? %v\n", srcImg.(*image.RGBA).Opaque())
	fmt.Printf("Destination opaque? %v\n", destImg.Opaque())
}
Пример #10
0
func load_losted_img(jsonstr string) (err error) {
	lostedobj, err := JsonToLostedChild(jsonstr)
	//map
	gpsx := strconv.FormatFloat(lostedobj.LostGPSX, 'f', -1, 64)

	gpsy := strconv.FormatFloat(lostedobj.LostGPSY, 'f', -1, 64)
	add := lostedobj.LostAddress
	if len(lostedobj.LostAddress) > 16 {
		add_rune := []rune(lostedobj.LostAddress)
		add = string(add_rune[0:12]) + "..."
	}

	map_url := "http://api.map.baidu.com/staticimage?center=" +
		gpsx + "," + gpsy + "&width=414&height=165&zoom=13&copyright=1" +
		"&labels=" + gpsx + "," + gpsy + "&labelStyles=" + url.QueryEscape(add) +
		",1,14,0x585858,0xffffff,0"
	baidu_map, err := GetImg(map_url)
	m_x, m_y := align(baidu_map.Bounds(), masker_img.Bounds())
	img_baidu_map = image.NewNRGBA(baidu_map.Bounds())
	draw.Draw(img_baidu_map, baidu_map.Bounds(), baidu_map, image.ZP, draw.Over)
	draw.Draw(img_baidu_map, offset(baidu_map.Bounds(), m_x, m_y-20), masker_img, image.ZP, draw.Over)
	head_pic, err := GetImg(lostedobj.FirstFacePic.PicUrl)
	head_smal = image.NewNRGBA(image.Rect(0, 0, 83, 83))
	err = graphics.Scale(head_smal, head_pic)
	head_circle = image.NewNRGBA(image.Rect(0, 0, 83, 83))
	draw.DrawMask(head_circle, head_circle.Bounds(), head_smal, image.ZP,
		&circle{image.Point{41, 41}, 41}, image.ZP, draw.Over)
	//find time
	sig_bd.FontSize = 13
	//lost height
	name, err = sig_bd.GetSimpalImage(lostedobj.BabyName, color_tbk, 2, 2)
	sig_bd.FontSize = 11.5
	sig_con.FontSize = 10
	sex_age, err = sig_con.GetSimpalImage(lostedobj.Sex+"  "+lostedobj.Age, color_con, 2, 2)
	sig_con.FontSize = 11.5
	img_lh_l, err = sig_bd.GetSimpalImage("走失时身高:", color_con, 2, 2)
	img_lt_l, err = sig_bd.GetSimpalImage("走失时间:", color_con, 2, 2)
	img_la_l, err = sig_bd.GetSimpalImage("走失地点:", color_con, 2, 2)
	//describe
	img_desc_l, err = sig_bd.GetSimpalImage("特征描述:", color_con, 2, 2)
	// current address
	img_ca_l, err = sig_bd.GetSimpalImage("现居地:", color_con, 2, 2)
	//contact
	img_contact_l, err = sig_bd.GetSimpalImage("联系人:", color_con, 2, 2)
	//phone
	img_phone_l, err = sig_bd.GetSimpalImage("联系电话:", color_con, 2, 2)
	//lost height right
	img_lh_r, err = sig_con.GetMoreLineImage(lostedobj.Height, color_con, 288, 2, 2)
	img_lt_r, err = sig_con.GetMoreLineImage(lostedobj.LostTime, color_con, 304, 2, 2)
	img_la_r, err = sig_con.GetMoreLineImage(lostedobj.LostAddress, color_con, 304, 2, 2)
	img_desc_r, err = sig_con.GetMoreLineImage(lostedobj.Describe, color_con, 304, 2, 2)
	img_ca_r, err = sig_con.GetMoreLineImage(lostedobj.Address, color_con, 320, 2, 2)
	img_contact_r, err = sig_con.GetMoreLineImage(lostedobj.Contacts, color_con, 320, 2, 2)
	img_phone_r, err = sig_con.GetMoreLineImage(lostedobj.TelNum, color_con, 304, 2, 2)
	length := len(lostedobj.OriPicUrlList)
	imglist = make([]image.Image, length, length)
	for i, chilpic := range lostedobj.OriPicUrlList {
		img_src, errr := GetImg(chilpic.PicUrl)
		err = errr
		bound := img_src.Bounds()
		dx := bound.Dx()
		dy := bound.Dy()
		dst := image.NewRGBA(image.Rect(0, 0, 414, 414*dy/dx))
		err = graphics.Scale(dst, img_src)
		imglist[i] = dst
	}
	return
}
Пример #11
0
func main() {
	fmt.Println(time.Now())
	obj, _ := JsonToObj("")
	//title text

	sig_bd := signer.NewSigner("./msyhbd.ttf")
	sig_bd.FontSize = 14
	white := image.NewUniform(color.NRGBA{255, 255, 255, 255})
	color_tbk := image.NewUniform(color.NRGBA{78, 187, 109, 255})
	//color_trans := color.NRGBA{0, 0, 0, 0}
	img_title_text, _ := sig_bd.GetSimpalImage("睿介寻子", white, color_tbk, 3, 3)
	//title back
	top_back_r := image.Rect(0, 0, 414, 57)
	img_tbk := image.NewNRGBA(top_back_r)
	// sum and align
	draw.Draw(img_tbk, img_tbk.Bounds(), color_tbk, image.ZP, draw.Src)
	x, y := align(top_back_r, img_title_text.Bounds())
	draw.Draw(img_tbk, offset(img_title_text.Bounds(), x, y-3), img_title_text, image.Point{0, 3}, draw.Src)

	//con
	sig_con := signer.NewSigner("./msyh.ttf")
	sig_con.FontSize = 11.5
	color_con := image.NewUniform(color.NRGBA{88, 88, 88, 255})

	//find time
	sig_bd.FontSize = 11.5
	img_ft_l, _ := sig_bd.GetSimpalImage("发现时间:", color_con, white, 2, 2)
	//describe
	img_desc_l, _ := sig_bd.GetSimpalImage("特征描述:", color_con, white, 2, 2)
	//find address
	img_fa_l, _ := sig_bd.GetSimpalImage("发现地点:", color_con, white, 2, 2)
	//find time right
	img_ft_r, _ := sig_con.GetMoreLineImage(obj.FindTime, color_con, white, 304, 2, 2)
	img_desc_r, _ := sig_con.GetMoreLineImage(obj.Describe, color_con, white, 304, 2, 2)
	img_fa_r, _ := sig_con.GetMoreLineImage(obj.FindAddress, color_con, white, 304, 2, 2)
	//map
	//http://api.map.baidu.com/staticimage?center=113.649644,34.75661&width=414&height=222&zoom=11
	gpsx := strconv.FormatFloat(obj.FindGPSX, 'f', -1, 64)
	//gpsx_off := strconv.FormatFloat(obj.FindGPSX-0.03, 'f', -1, 64)
	//gpsy_off := strconv.FormatFloat(obj.FindGPSY-0.005, 'f', -1, 64)
	gpsy := strconv.FormatFloat(obj.FindGPSY, 'f', -1, 64)
	add := obj.FindAddress
	if len(obj.FindAddress) > 16 {
		add_rune := []rune(obj.FindAddress)
		add = string(add_rune[0:12]) + "..."
	}

	map_url := "http://api.map.baidu.com/staticimage?center=" +
		gpsx + "," + gpsy + "&width=414&height=222&zoom=13&copyright=1" +
		"&labels=" + gpsx + "," + gpsy + "&labelStyles=" + url.QueryEscape(add) +
		",1,12,0x585858,0xffffff,0"
	fmt.Println(map_url)
	baidu_map, _ := GetImg(map_url)
	//masker_img, _ := GetImg("http://7xl130.com1.z0.glb.clouddn.com/mask.png")
	masker, _ := os.Open("./mask.png")
	masker_img, _ := png.Decode(masker)
	m_x, m_y := align(baidu_map.Bounds(), masker_img.Bounds())
	fmt.Println(m_x, m_y)
	img_baidu_map := image.NewNRGBA(baidu_map.Bounds())
	draw.Draw(img_baidu_map, baidu_map.Bounds(), baidu_map, image.ZP, draw.Src)
	draw.Draw(img_baidu_map, offset(baidu_map.Bounds(), m_x, m_y-20), masker_img, image.ZP, draw.Over)

	length := len(obj.PicUrlList)
	imglist := make([]image.Image, length, length)
	for i, chilpic := range obj.PicUrlList {
		fmt.Println(time.Now())
		img_src, _ := GetImg(chilpic.PicUrl)
		fmt.Println(time.Now())
		bound := img_src.Bounds()
		dx := bound.Dx()
		dy := bound.Dy()
		dst := image.NewRGBA(image.Rect(0, 0, 414, 414*dy/dx))
		err := graphics.Scale(dst, img_src)
		fmt.Println(time.Now())
		if err != nil {
			fmt.Println("Scale Image failed")
		}
		imglist[i] = dst
	}
	//img_bottom, _ := GetImg("http://7xl130.com1.z0.glb.clouddn.com/bottom.png")
	bottom, _ := os.Open("./bottom.png")
	img_bottom, _ := png.Decode(bottom)
	img_h := 0
	img_h += 57                         //top
	img_h += imglist[0].Bounds().Dy()   //the head baby image
	img_h += 22                         //text top
	img_h += 20                         //text middle
	img_h += 18                         //text bottom
	img_h += 222                        //map height
	img_h += 23                         ///map bottom
	for i := 1; i < len(imglist); i++ { //image height
		img_h += imglist[i].Bounds().Dy()
		img_h += 12
	}
	img_h -= 12
	img_h += 315                      //qr code and logo
	img_h += img_ft_r.Bounds().Dy()   //find time height
	img_h += img_desc_r.Bounds().Dy() //desc height
	img_h += img_fa_r.Bounds().Dy()   //find address height
	//create result image
	result_r := image.Rect(0, 0, 414, img_h)
	result_img := image.NewNRGBA(result_r)
	draw.Draw(result_img, result_r, white, image.ZP, draw.Src)
	offset_height := 0
	//draw top
	draw.Draw(result_img, top_back_r, img_tbk, image.ZP, draw.Src) //draw top
	offset_height += 57
	//draw first child image
	draw.Draw(result_img, offset(imglist[0].Bounds(), 0, offset_height), imglist[0], image.ZP, draw.Src)
	offset_height += imglist[0].Bounds().Dy()
	offset_height += 22
	//draw find time
	draw.Draw(result_img, offset(img_ft_l.Bounds(), 4, offset_height), img_ft_l, image.Point{0, 2}, draw.Src)
	draw.Draw(result_img, offset(img_ft_r.Bounds(), 90, offset_height+3), img_ft_r, image.Point{0, 2}, draw.Src)
	offset_height += img_ft_r.Bounds().Dy()
	offset_height += 10
	//draw find desc
	draw.Draw(result_img, offset(img_desc_l.Bounds(), 4, offset_height), img_desc_l, image.Point{0, 2}, draw.Src)
	draw.Draw(result_img, offset(img_desc_r.Bounds(), 90, offset_height+3), img_desc_r, image.Point{0, 2}, draw.Src)
	offset_height += img_desc_r.Bounds().Dy()
	offset_height += 10
	//draw find address
	draw.Draw(result_img, offset(img_fa_l.Bounds(), 4, offset_height), img_fa_l, image.Point{0, 2}, draw.Src)
	draw.Draw(result_img, offset(img_fa_r.Bounds(), 90, offset_height+3), img_fa_r, image.Point{0, 2}, draw.Src)
	offset_height += img_fa_r.Bounds().Dy()
	offset_height += 18
	//draw map
	draw.Draw(result_img, offset(img_baidu_map.Bounds(), 0, offset_height), img_baidu_map, image.ZP, draw.Src)
	offset_height += img_baidu_map.Bounds().Dy()
	offset_height += 23
	//draw child pic
	for i := 1; i < len(imglist); i++ { //image height
		draw.Draw(result_img, offset(imglist[i].Bounds(), 0, offset_height), imglist[i], image.ZP, draw.Src)
		offset_height += imglist[i].Bounds().Dy()
		offset_height += 12
	}
	img_h -= 12
	//draw qrcode and logo
	draw.Draw(result_img, offset(img_bottom.Bounds(), 0, offset_height), img_bottom, image.ZP, draw.Src)

	f, _ := os.Create("./test.png")
	defer f.Close()
	png.Encode(f, result_img)
	fmt.Println(time.Now())
	/*
		resp, err := http.Get("http://7xl130.com1.z0.glb.clouddn.com/back.png")
		if err != nil {
			fmt.Println("Error:" + err.Error())
		} else {
			//length, _ := strconv.ParseInt(resp.Header.Get("Content-Length"), 10, 0)
			content_type := resp.Header.Get("Content-Type")

			switch strings.TrimPrefix(content_type, "image/") {
			case "png":
				img, _ := png.Decode(resp.Body)
				text :=

				fmt.Println(img.ColorModel())
			}

		}
	*/
}
Пример #12
0
// Scale is a simple wrapper around graphics.Scale.
func Scale(img image.Image, width, height int) draw.Image {
	dimg := image.NewRGBA(image.Rect(0, 0, width, height))
	graphics.Scale(dimg, img)

	return dimg
}
Пример #13
0
// Converts image to text version
func convertImage(img image.Image, settings map[string]interface{}) (result []byte, err error) {

	// Set up parameters
	var p parameters
	p = defaults()

	if v, ok := settings["bgcolor"].(string); ok && len(v) > 0 {
		p.bgcolor = v
	}
	if v, ok := settings["browser"].(string); ok && len(v) > 0 {
		p.browser = v
	}
	if v, ok := settings["characters"].(string); ok && len(v) > 0 {
		p.characters = v
	}
	if v, ok := settings["contrast"].(string); ok && len(v) > 0 {
		p.contrast, _ = strconv.Atoi(v)
	}
	if v, ok := settings["fontsize"].(string); ok && len(v) > 0 {
		p.fontsize = v
	}
	if v, ok := settings["grayscale"].(string); ok && len(v) > 0 {
		p.grayscale, _ = strconv.Atoi(v)
	}
	if v, ok := settings["textType"].(string); ok && len(v) > 0 {
		p.texttype = v
	}
	if v, ok := settings["width"].(string); ok && len(v) > 0 {
		p.width, _ = strconv.Atoi(v)
		if p.width < 1 || p.width > 500 {
			p.width = 100
		}
	}

	// Rescale proportions to make output prettier in text
	height := int(float32(p.width) / (float32(img.Bounds().Dx()) / float32(img.Bounds().Dy())))
	if p.browser == "ie" {
		height = height * 65 / 100
	} else {
		height = height * 43 / 100
	}

	// Produce minified image to work with
	start := time.Now()
	var m *image.RGBA
	if p.width < img.Bounds().Dx() && p.width >= 150 && (img.Bounds().Dx()*img.Bounds().Dy()/p.width) < 5000 {
		temp, err := resize(img, p.width, height)
		if err != nil {
			return result, err
		}
		m = temp.(*image.RGBA)
	} else {
		m = image.NewRGBA(image.Rect(0, 0, p.width, height))
		graphics.Scale(m, img)
	}

	// Modify image as required
	if p.grayscale == 1 {
		grayscale(m)
	} else if p.grayscale == 2 {
		monochrome(m)
	}

	// Initialize buffer
	var buffer bytes.Buffer
	buffer.WriteString("<table align=\"center\" cellpadding=\"10\">\n<tr bgcolor=\"" + p.bgcolor + "\"><td>\n\n")
	buffer.WriteString("<!-- IMAGE BEGINS HERE -->\n<font size=\"" + p.fontsize + "\">\n<pre>")

	// Prepare variables
	htmlStart := "<font color=#"
	htmlEnd := "</font>"
	var current, previous uint = 0, 0
	next := nextChar(p.texttype, p.characters)
	b := m.Bounds()

	// Loop over all pixels and add HTML-font converted data to the output buffer
	for y := b.Min.Y; y < b.Max.Y; y++ {
		j := m.PixOffset(0, y)
		current = uint(m.Pix[j+0])<<16 | uint(m.Pix[j+1])<<8 | uint(m.Pix[j+2])
		buffer.WriteString(htmlStart + hex(current) + ">" + next())
		previous = current

		for x := b.Min.X + 1; x < b.Max.X; x++ {
			i := m.PixOffset(x, y)
			current = uint(m.Pix[i+0])<<16 | uint(m.Pix[i+1])<<8 | uint(m.Pix[i+2])
			if previous != current {
				buffer.WriteString(htmlEnd + htmlStart + hex(current) + ">" + next())
			} else {
				buffer.WriteString(next())
			}
			previous = current
		}

		buffer.WriteString(htmlEnd + "<br>")
	}

	// Finish up buffer
	buffer.WriteString("\n</pre></font>")
	buffer.WriteString("\n<!-- IMAGE ENDS HERE -->\n")
	buffer.WriteString("\n<FONT COLOR=LIGHTBLUE SIZE=2>Rendering time: " + time.Since(start).String() + "</FONT><BR>\n")

	result = buffer.Bytes()
	return
}
Пример #14
0
// VersionSourceRect searches and returns an existing matching version,
// or a new one will be created and saved.
func (self *Image) VersionSourceRect(sourceRect image.Rectangle, width, height int, grayscale bool, outsideColor color.Color) (im *ImageVersion, err error) {
	debug.Nop()
	// debug.Printf(
	// 	"VersionSourceRect: from %dx%d image take rectangle [%d,%d,%d,%d] (%dx%d) and scale it to %dx%d",
	// 	self.Width(),
	// 	self.Height(),
	// 	sourceRect.Min.X,
	// 	sourceRect.Min.Y,
	// 	sourceRect.Max.X,
	// 	sourceRect.Max.Y,
	// 	sourceRect.Dx(),
	// 	sourceRect.Dy(),
	// 	width,
	// 	height,
	// )

	if self.Grayscale() {
		grayscale = true // Ignore color requests when original image is grayscale
	}

	// Search for exact match
	for i := range self.Versions {
		v := &self.Versions[i]
		match := v.SourceRect.Rectangle() == sourceRect &&
			v.Width.GetInt() == width &&
			v.Height.GetInt() == height &&
			v.OutsideColor.EqualsColor(outsideColor) &&
			v.Grayscale.Get() == grayscale
		if match {
			return v, nil
		}
	}

	// No exact match, create version
	origImage, err := self.Versions[0].LoadImage()
	if err != nil {
		return nil, err
	}

	var versionImage image.Image
	if grayscale {
		versionImage = image.NewGray(image.Rect(0, 0, width, height))
	} else {
		versionImage = image.NewRGBA(image.Rect(0, 0, width, height))
	}
	if sourceRect.In(self.Rectangle()) {
		// debug.Print("VersionSourceRect: rectangle is within image")

		// versionImage = ResampleImage(origImage, sourceRect, width, height)
		subImage := SubImageWithoutOffset(origImage, sourceRect)
		err = graphics.Scale(versionImage.(draw.Image), subImage)
		if err != nil {
			return nil, err
		}
		if grayscale && !self.Grayscale() {
			var grayVersion image.Image = image.NewGray(versionImage.Bounds())
			draw.Draw(grayVersion.(draw.Image), versionImage.Bounds(), versionImage, image.ZP, draw.Src)
			versionImage = grayVersion
		}
	} else {
		// debug.Print("VersionSourceRect: rectangle is not completely within image, using outsideColor")

		// Fill version with outsideColor
		draw.Draw(versionImage.(draw.Image), versionImage.Bounds(), image.NewUniform(outsideColor), image.ZP, draw.Src)
		// Where to draw the source image into the version image
		var destRect image.Rectangle
		if !(sourceRect.Min.X < 0 || sourceRect.Min.Y < 0) {
			panic("touching from outside means that sourceRect x or y must be negative")
		}
		sourceW := float64(sourceRect.Dx())
		sourceH := float64(sourceRect.Dy())
		destRect.Min.X = int(float64(-sourceRect.Min.X) / sourceW * float64(width))
		destRect.Min.Y = int(float64(-sourceRect.Min.Y) / sourceH * float64(height))
		destRect.Max.X = destRect.Min.X + int(float64(self.Width())/sourceW*float64(width))
		destRect.Max.Y = destRect.Min.Y + int(float64(self.Height())/sourceH*float64(height))

		// destImage := ResampleImage(origImage, origImage.Bounds(), destRect.Dx(), destRect.Dy())
		// draw.Draw(versionImage.(draw.Image), destRect, destImage, image.ZP, draw.Src)
		subImage := SubImageWithoutOffset(origImage, sourceRect)
		destImage := SubImageWithoutOffset(versionImage, destRect)
		err = graphics.Scale(destImage.(draw.Image), subImage)
		if err != nil {
			return nil, err
		}
	}

	// Save new image version
	version := self.addVersion(self.Filename(), self.ContentType(), sourceRect, width, height, grayscale)
	err = version.SaveImage(versionImage)
	if err != nil {
		return nil, err
	}
	err = self.Save()
	if err != nil {
		return nil, err
	}
	return version, nil
}