func NewPicture(bounds image.Rectangle) *Picture { return &Picture{ Data: make([]float64, bounds.Dx()*bounds.Dy()), Gamma: 1.0, //2.2, Rect: bounds, } }
// Resample returns a resampled copy of the image slice r of m. // The returned image has width w and height h. func Resample(m image.Image, r image.Rectangle, w, h int) image.Image { if w < 0 || h < 0 { return nil } if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 { return image.NewRGBA64(image.Rect(0, 0, w, h)) } img := image.NewRGBA(image.Rect(0, 0, w, h)) xStep := float64(r.Dx()) / float64(w) yStep := float64(r.Dy()) / float64(h) for y := 0; y < h; y++ { for x := 0; x < w; x++ { xSrc := int(float64(r.Min.X) + float64(x)*xStep) ySrc := int(float64(r.Min.Y) + float64(y)*yStep) r, g, b, a := m.At(xSrc, ySrc).RGBA() img.SetRGBA(x, y, color.RGBA{ R: uint8(r >> 8), G: uint8(g >> 8), B: uint8(b >> 8), A: uint8(a >> 8), }) } } return img }
func (c *NativeCanvas) BlitToContext(nc NativeContext, x int, y int, srcRc *image.Rectangle) { // log.Printf("NativeCanvas.BlitToContext(...)") var srcDC = c.BeginPaint() if srcRc == nil { var tempRc = image.Rect(0, 0, c.W(), c.H()) srcRc = &tempRc } var copyWidth = srcRc.Dx() var copyHeight = srcRc.Dy() if c.Opaque() { // log.Printf("BitBlt(%v %v %v)", x, y, *srcRc) var err = BitBlt(Handle(nc), int32(x), int32(y), int32(copyWidth), int32(copyHeight), Handle(srcDC), int32(srcRc.Min.X), int32(srcRc.Min.Y), SRCCOPY) if err != nil { log.Printf("BitBlt(...) %v", err) } } else { var bf = BLENDFUNCTION{AC_SRC_OVER, 0, 255, AC_SRC_ALPHA} GdiAlphaBlend(Handle(nc), int32(x), int32(y), int32(copyWidth), int32(copyHeight), Handle(srcDC), int32(srcRc.Min.X), int32(srcRc.Min.Y), int32(copyWidth), int32(copyHeight), bf) } c.EndPaint() }
func Make(r image.Rectangle) *Image { return &Image{ Pix: make([]byte, r.Dx()*r.Dy()*3), Stride: r.Dx() * 3, Rect: image.Rect(0, 0, r.Dx(), r.Dy()), } }
func MakeWithData(r image.Rectangle, pix []byte) *Image { return &Image{ Pix: pix, Stride: r.Dx() * 3, Rect: image.Rect(0, 0, r.Dx(), r.Dy()), } }
func (ts *ThumbnailSpec) CalculateRect(rect image.Rectangle) (w int, h int) { if ts.Width == 0 && ts.Height == 0 { panic("tenpu/thumbnails: must provide width, or height for thumbnails.") } if ts.Height == 0 { w = ts.Width h = int((float64(ts.Width) / float64(rect.Dx())) * float64(rect.Dy())) return } if ts.Width == 0 { h = ts.Height w = int((float64(ts.Height) / float64(rect.Dy())) * float64(rect.Dx())) return } if (float64(ts.Width)/float64(rect.Dx()))*float64(rect.Dy()) > float64(ts.Height) { h = ts.Height w = int((float64(ts.Height) / float64(rect.Dy())) * float64(rect.Dx())) return } w = ts.Width h = int((float64(ts.Width) / float64(rect.Dx())) * float64(rect.Dy())) return }
func (p *resizeToFitFilter) Bounds(srcBounds image.Rectangle) image.Rectangle { w, h := p.width, p.height srcw, srch := srcBounds.Dx(), srcBounds.Dy() if w <= 0 || h <= 0 || srcw <= 0 || srch <= 0 { return image.Rect(0, 0, 0, 0) } if srcw <= w && srch <= h { return image.Rect(0, 0, srcw, srch) } wratio := float64(srcw) / float64(w) hratio := float64(srch) / float64(h) var dstw, dsth int if wratio > hratio { dstw = w dsth = minint(int(float64(srch)/wratio+0.5), h) } else { dsth = h dstw = minint(int(float64(srcw)/hratio+0.5), w) } return image.Rect(0, 0, dstw, dsth) }
func RelBounds(r, b image.Rectangle) (n Bounds) { n.Min.X = float32(r.Min.X-b.Min.X) / float32(b.Dx()) n.Min.Y = float32(r.Min.Y-b.Min.Y) / float32(b.Dy()) n.Max.X = float32(r.Max.X-b.Min.X) / float32(b.Dx()) n.Max.Y = float32(r.Max.Y-b.Min.Y) / float32(b.Dy()) return n }
func newEanCoordinateConverter(outerBound image.Rectangle, fm fontMeasurer) (*eanCoordinateConverter, error) { const rightMargin = digitBarSize const logicalWidth = 13*digitBarSize + startMarkerSize + endMarkerSize + centerMarkerSize + rightMargin scale := outerBound.Dx() / logicalWidth if scale <= 0 { return nil, errAreaTooSmall } xMargin := (outerBound.Dx() % logicalWidth) / 2 fSize, fWidth, fHeight := fm(digitBarSize * scale) if digitBarSize*scale < fWidth { return nil, errFontTooBig } if outerBound.Dy() < fHeight*2 { return nil, errAreaTooSmall } return &eanCoordinateConverter{ bound: image.Rectangle{ Min: outerBound.Min.Add(image.Pt(xMargin, 0)), Max: outerBound.Max.Sub(image.Pt(xMargin, 0)), }, fontDim: image.Rect(0, 0, fWidth, fHeight), scale: scale, fontSize: fSize, }, nil }
func Crop(m image.Image, r image.Rectangle, w, h int) image.Image { if w < 0 || h < 0 { return nil } if w == 0 || h == 0 || r.Dx() <= 0 || r.Dy() <= 0 { return image.NewRGBA64(image.Rect(0, 0, w, h)) } curw, curh := r.Min.X, r.Min.Y img := image.NewRGBA(image.Rect(0, 0, w, h)) for y := 0; y < h; y++ { for x := 0; x < w; x++ { // Get a source pixel. subx := curw + x suby := curh + y r32, g32, b32, a32 := m.At(subx, suby).RGBA() r := uint8(r32 >> 8) g := uint8(g32 >> 8) b := uint8(b32 >> 8) a := uint8(a32 >> 8) img.SetRGBA(x, y, color.RGBA{r, g, b, a}) } } return img }
// Takes a bounding box in an image r. // Coerces it to the aspect ratio of target.Int according to mode. // Returns the rectangle which, when resized to target.Size, // will have the bounding box in target.Int. // Panics if the target has non-positive interior. func FitRect(orig image.Rectangle, target PadRect, mode string) (scale float64, fit image.Rectangle) { if target.Int.Dx() <= 0 || target.Int.Dy() <= 0 { panic("empty interior") } if mode == "stretch" { panic("stretch mode not supported by FitRect") } aspect := float64(target.Int.Dx()) / float64(target.Int.Dy()) // Width and height of box in image. w, h := float64(orig.Dx()), float64(orig.Dy()) // Co-erce size to match aspect ratio. w, h = SetAspect(w, h, aspect, mode) // If source is smaller than target, then scale is > 1 (i.e. need to magnify). scale = float64(target.Int.Dx()) / w // == float64(target.Int.Dy()) / h // Get position of interior centroid in target rectangle. left, top := centroid(target.Int) right, bottom := float64(target.Size.X)-left, float64(target.Size.Y)-top // Get position of centroid of original bounding box in image. x, y := centroid(orig) // Scale offsets on all sides and add to centroid for final rectangle. // If scale is greater than 1 then source is smaller than target. // Then the rectangle in the source image is shrunk (i.e. divide by scale). x0, x1 := x-left/scale, x+right/scale y0, y1 := y-top/scale, y+bottom/scale fit = image.Rect(round(x0), round(y0), round(x1), round(y1)) return }
// New returns a new Image with the given bounds and subsample ratio. func New(r image.Rectangle, subsampleRatio image.YCbCrSubsampleRatio) *Image { // TODO: share code with image.NewYCbCr when this type moves into the // standard image package. w, h, cw, ch := r.Dx(), r.Dy(), 0, 0 switch subsampleRatio { case image.YCbCrSubsampleRatio422: cw = (r.Max.X+1)/2 - r.Min.X/2 ch = h case image.YCbCrSubsampleRatio420: cw = (r.Max.X+1)/2 - r.Min.X/2 ch = (r.Max.Y+1)/2 - r.Min.Y/2 case image.YCbCrSubsampleRatio440: cw = w ch = (r.Max.Y+1)/2 - r.Min.Y/2 default: // Default to 4:4:4 subsampling. cw = w ch = h } b := make([]byte, 2*w*h+2*cw*ch) // TODO: use s[i:j:k] notation to set the cap. return &Image{ YCbCr: image.YCbCr{ Y: b[:w*h], Cb: b[w*h+0*cw*ch : w*h+1*cw*ch], Cr: b[w*h+1*cw*ch : w*h+2*cw*ch], SubsampleRatio: subsampleRatio, YStride: w, CStride: cw, Rect: r, }, A: b[w*h+2*cw*ch:], AStride: w, } }
// NewYCbCrAligned Allocates YCbCr image with padding. // Because LibJPEG needs extra padding to decoding buffer, This func add an // extra alignSize (16) padding to cover overflow from any such modes. func NewYCbCrAligned(r image.Rectangle, subsampleRatio image.YCbCrSubsampleRatio) *image.YCbCr { w, h, cw, ch := r.Dx(), r.Dy(), 0, 0 switch subsampleRatio { case image.YCbCrSubsampleRatio422: cw = (r.Max.X+1)/2 - r.Min.X/2 ch = h case image.YCbCrSubsampleRatio420: cw = (r.Max.X+1)/2 - r.Min.X/2 ch = (r.Max.Y+1)/2 - r.Min.Y/2 case image.YCbCrSubsampleRatio440: cw = w ch = (r.Max.Y+1)/2 - r.Min.Y/2 default: cw = w ch = h } // TODO: check the padding size to minimize memory allocation. yStride := pad(w, alignSize) + alignSize cStride := pad(cw, alignSize) + alignSize yHeight := pad(h, alignSize) + alignSize cHeight := pad(ch, alignSize) + alignSize b := make([]byte, yStride*yHeight+2*cStride*cHeight) return &image.YCbCr{ Y: b[:yStride*yHeight], Cb: b[yStride*yHeight+0*cStride*cHeight : yStride*yHeight+1*cStride*cHeight], Cr: b[yStride*yHeight+1*cStride*cHeight : yStride*yHeight+2*cStride*cHeight], SubsampleRatio: subsampleRatio, YStride: yStride, CStride: cStride, Rect: r, } }
// PackHorzontal finds the Pos for a horizontally packed sprite func (l *ImageList) PackHorizontal(pos int) Pos { if pos == -1 || pos == 0 { return Pos{0, 0} } var x, y int var rect image.Rectangle // there are n-1 paddings in an image list x = l.Padding * pos // No padding on the outside of the image if pos == len(l.GoImages) { x -= l.Padding } for i := 1; i <= pos; i++ { rect = l.GoImages[i-1].Bounds() x += rect.Dx() if pos == len(l.GoImages) { y = int(math.Max(float64(y), float64(rect.Dy()))) } } return Pos{ x, y, } }
func (opts *DecodeOpts) wantRescale(b image.Rectangle, swapDimensions bool) bool { if opts == nil { return false } // In rescale Scale* trumps Max* so we assume the same relationship here. // Floating point compares probably only allow this to work if the values // were specified as the literal 1 or 1.0, computed values will likely be // off. If Scale{Width,Height} end up being 1.0-epsilon we'll rescale // when it probably wouldn't even be noticible but that's okay. if opts.ScaleWidth == 1.0 && opts.ScaleHeight == 1.0 { return false } if opts.ScaleWidth > 0 && opts.ScaleWidth < 1.0 || opts.ScaleHeight > 0 && opts.ScaleHeight < 1.0 { return true } w, h := b.Dx(), b.Dy() if swapDimensions { w, h = h, w } // Same size, don't rescale. if opts.MaxWidth == w && opts.MaxHeight == h { return false } return opts.MaxWidth > 0 && opts.MaxWidth < w || opts.MaxHeight > 0 && opts.MaxHeight < h }
// CenterFit produces the affine transform, centered around the rectangles. // It is equivalent to // I.Translate(-<center of src>).Mul(a).Translate(<center of dst>) func (a Affine) CenterFit(dst, src image.Rectangle) Affine { dx := float64(dst.Min.X) + float64(dst.Dx())/2 dy := float64(dst.Min.Y) + float64(dst.Dy())/2 sx := float64(src.Min.X) + float64(src.Dx())/2 sy := float64(src.Min.Y) + float64(src.Dy())/2 return I.Translate(-sx, -sy).Mul(a).Translate(dx, dy) }
func drawCopySrc(dst *image.RGBA, r image.Rectangle, src *image.RGBA, sp image.Point) { n, dy := 4*r.Dx(), r.Dy() d0 := dst.PixOffset(r.Min.X, r.Min.Y) s0 := src.PixOffset(sp.X, sp.Y) var ddelta, sdelta int if r.Min.Y <= sp.Y { ddelta = dst.Stride sdelta = src.Stride } else { // If the source start point is higher than the destination start // point, then we compose the rows in bottom-up order instead of // top-down. Unlike the drawCopyOver function, we don't have to check // the x coordinates because the built-in copy function can handle // overlapping slices. d0 += (dy - 1) * dst.Stride s0 += (dy - 1) * src.Stride ddelta = -dst.Stride sdelta = -src.Stride } for ; dy > 0; dy-- { copy(dst.Pix[d0:d0+n], src.Pix[s0:s0+n]) d0 += ddelta s0 += sdelta } }
// PackHorzontal finds the Pos for a horizontally packed sprite func (l *Sprite) PackHorizontal(pos int) Pos { if pos == -1 || pos == 0 { return Pos{0, 0} } var x, y int var rect image.Rectangle l.optsMu.RLock() padding := l.opts.Padding l.optsMu.RUnlock() // there are n-1 paddings in an image list x = padding * pos // No padding on the outside of the image numimages := l.Len() if pos == numimages { x -= padding } for i := 1; i <= pos; i++ { l.goImagesMu.RLock() rect = l.imgs[i-1].Bounds() l.goImagesMu.RUnlock() x += rect.Dx() if pos == numimages { y = int(math.Max(float64(y), float64(rect.Dy()))) } } return Pos{ x, y, } }
func AverageNRGBA64(rect image.Rectangle, img *image.NRGBA64) color.NRGBA64 { // Only use the area of the rectangle that overlaps with the image bounds. rect = rect.Intersect(img.Bounds()) // Determine whether or not there's any area over which to determine an // average. d := uint64(rect.Dx() * rect.Dy()) if d == 0 { return color.NRGBA64{} } var r, g, b, a uint64 AllPointsRP( func(pt image.Point) { c := img.NRGBA64At(pt.X, pt.Y) r += uint64(c.R) g += uint64(c.G) b += uint64(c.B) a += uint64(c.A) }, )(rect) return color.NRGBA64{ R: uint16(r / d), G: uint16(g / d), B: uint16(b / d), A: uint16(a / d), } }
// Thumbnail scales and crops src so it fits in dst. func Thumbnail(dst draw.Image, src image.Image) error { // Scale down src in the dimension that is closer to dst. sb := src.Bounds() db := dst.Bounds() rx := float64(sb.Dx()) / float64(db.Dx()) ry := float64(sb.Dy()) / float64(db.Dy()) var b image.Rectangle if rx < ry { b = image.Rect(0, 0, db.Dx(), int(float64(sb.Dy())/rx)) } else { b = image.Rect(0, 0, int(float64(sb.Dx())/ry), db.Dy()) } buf := image.NewRGBA(b) if err := Scale(buf, src); err != nil { return err } // Crop. // TODO(crawshaw): improve on center-alignment. var pt image.Point if rx < ry { pt.Y = (b.Dy() - db.Dy()) / 2 } else { pt.X = (b.Dx() - db.Dx()) / 2 } draw.Draw(dst, db, buf, pt, draw.Src) return nil }
func (opts *DecodeOpts) wantRescale(b image.Rectangle) bool { return opts != nil && (opts.MaxWidth > 0 && opts.MaxWidth < b.Dx() || opts.MaxHeight > 0 && opts.MaxHeight < b.Dy() || opts.ScaleWidth > 0.0 && opts.ScaleWidth < float32(b.Dx()) || opts.ScaleHeight > 0.0 && opts.ScaleHeight < float32(b.Dy())) }
func (a *area) Repaint(r image.Rectangle) { r = image.Rect(0, 0, a.width, a.height).Intersect(r) if r.Empty() { return } println(a._widget, C.gint(r.Min.X), C.gint(r.Min.Y), C.gint(r.Dx()), C.gint(r.Dy())) C.gtk_widget_queue_draw_area(a._widget, C.gint(r.Min.X), C.gint(r.Min.Y), C.gint(r.Dx()), C.gint(r.Dy())) }
func saneRectangle(rect image.Rectangle) image.Rectangle { rect = rect.Canon() width, height := rect.Dx(), rect.Dy() if width < 1 || width > 4096 || height < 1 || height > 4096 { return image.Rect(0, 0, 16, 16) } return rect }
// New creates a new Frame bounded by a rectangle r func New(r image.Rectangle) *Frame { var w, h = r.Dx(), r.Dy() return &Frame{ Data: make([]Cell, w*h), Bounds: r, Stride: r.Dx(), } }
//DrawElementsInArea is used for redrawing func (b *Backend) DrawElementsInArea(l gs.DrawPriorityList, area image.Rectangle) { gl.Enable(gl.SCISSOR_TEST) gl.Scissor(area.Min.X, area.Min.Y, area.Dx(), area.Dy()) for _, o := range l { o.Draw(b) } gl.Disable(gl.SCISSOR_TEST) }
// SetOrtho sets this camera's Projection matrix to an orthographic one. // // The view parameter is the viewing rectangle for the orthographic // projection in window coordinates. // // The near and far parameters describe the minimum closest and maximum // furthest clipping points of the view frustum. // // Clients who need advanced control over how the orthographic viewing frustum // is set up may use this method's source as a reference (e.g. to change the // center point, which this method sets at the bottom-left). // // Write access is required for this method to operate safely. func (c *Camera) SetOrtho(view image.Rectangle, near, far float64) { w := float64(view.Dx()) w = float64(int((w / 2.0)) * 2) h := float64(view.Dy()) h = float64(int((h / 2.0)) * 2) m := math.Mat4Ortho(0, w, 0, h, near, far) c.Projection = ConvertMat4(m) }
func (p *transformFilter) Bounds(srcBounds image.Rectangle) (dstBounds image.Rectangle) { if p.tt == ttRotate90 || p.tt == ttRotate270 || p.tt == ttTranspose || p.tt == ttTransverse { dstBounds = image.Rect(0, 0, srcBounds.Dy(), srcBounds.Dx()) } else { dstBounds = image.Rect(0, 0, srcBounds.Dx(), srcBounds.Dy()) } return }
// Create a new Image64 with the rectangle's width and height. func NewImage64(r image.Rectangle) *Image64 { width, height := r.Dx(), r.Dy() return &Image64{ Pix: make([]Color64, width*height), Stride: width, Rect: image.Rectangle{image.ZP, image.Point{width, height}}, } }
// Scale implements the Scale method of the screen.Drawer interface by calling // the Draw method of that same interface. func Scale(dst screen.Drawer, dr image.Rectangle, src screen.Texture, sr image.Rectangle, op draw.Op, opts *screen.DrawOptions) { rx := float64(dr.Dx()) / float64(sr.Dx()) ry := float64(dr.Dy()) / float64(sr.Dy()) dst.Draw(f64.Aff3{ rx, 0, float64(dr.Min.X) - rx*float64(sr.Min.X), 0, ry, float64(dr.Min.Y) - ry*float64(sr.Min.Y), }, src, sr, op, opts) }
func NewBuffered(r image.Rectangle, border termbox.Cell) *Buffered { b := &Buffered{ Unbuffered: Unbuffered{r: r, border: border}, buffer: make([]termbox.Cell, r.Dx()*r.Dy()), } b.Clear() return b }