github.com/jmigpin/editor@v1.6.0/util/imageutil/misc.go (about)

     1  package imageutil
     2  
     3  import (
     4  	"image"
     5  	"image/color"
     6  	"image/draw"
     7  	"math"
     8  )
     9  
    10  func DrawMask(
    11  	dst draw.Image,
    12  	r image.Rectangle,
    13  	src image.Image, srcp image.Point,
    14  	mask image.Image, maskp image.Point,
    15  	op draw.Op,
    16  ) {
    17  	// improve performance for bgra
    18  	if bgra, ok := dst.(*BGRA); ok {
    19  		dst = &bgra.RGBA
    20  	}
    21  
    22  	draw.DrawMask(dst, r, src, srcp, mask, maskp, op)
    23  }
    24  
    25  //----------
    26  
    27  func DrawUniformMask(
    28  	dst draw.Image,
    29  	r image.Rectangle,
    30  	c color.Color,
    31  	mask image.Image, maskp image.Point,
    32  	op draw.Op,
    33  ) {
    34  	if c == nil {
    35  		return
    36  	}
    37  	// correct color for bgra
    38  	if _, ok := dst.(*BGRA); ok {
    39  		c = BgraColor(c)
    40  	}
    41  
    42  	src := image.NewUniform(c)
    43  	srcp := image.ZP
    44  	DrawMask(dst, r, src, srcp, mask, maskp, op)
    45  }
    46  
    47  func DrawUniform(dst draw.Image, r image.Rectangle, c color.Color, op draw.Op) {
    48  	DrawUniformMask(dst, r, c, nil, image.ZP, op)
    49  }
    50  
    51  //----------
    52  
    53  func DrawCopy(dst draw.Image, r image.Rectangle, src image.Image) {
    54  	DrawMask(dst, r, src, image.ZP, nil, image.ZP, draw.Src)
    55  }
    56  
    57  //----------
    58  
    59  func FillRectangle(img draw.Image, r image.Rectangle, c color.Color) {
    60  	DrawUniform(img, r, c, draw.Src)
    61  }
    62  
    63  func BorderRectangle(img draw.Image, r image.Rectangle, c color.Color, size int) {
    64  	var sr [4]image.Rectangle
    65  	// top
    66  	sr[0] = r
    67  	sr[0].Max.Y = r.Min.Y + size
    68  	// bottom
    69  	sr[1] = r
    70  	sr[1].Min.Y = r.Max.Y - size
    71  	// left
    72  	sr[2] = r
    73  	sr[2].Max.X = r.Min.X + size
    74  	sr[2].Min.Y = r.Min.Y + size
    75  	sr[2].Max.Y = r.Max.Y - size
    76  	// right
    77  	sr[3] = r
    78  	sr[3].Min.X = r.Max.X - size
    79  	sr[3].Min.Y = r.Min.Y + size
    80  	sr[3].Max.Y = r.Max.Y - size
    81  
    82  	for _, r2 := range sr {
    83  		r2 = r2.Intersect(r)
    84  		DrawUniform(img, r2, c, draw.Src)
    85  	}
    86  }
    87  
    88  //----------
    89  
    90  func MaxPoint(p1, p2 image.Point) image.Point {
    91  	if p1.X < p2.X {
    92  		p1.X = p2.X
    93  	}
    94  	if p1.Y < p2.Y {
    95  		p1.Y = p2.Y
    96  	}
    97  	return p1
    98  }
    99  func MinPoint(p1, p2 image.Point) image.Point {
   100  	if p1.X > p2.X {
   101  		p1.X = p2.X
   102  	}
   103  	if p1.Y > p2.Y {
   104  		p1.Y = p2.Y
   105  	}
   106  	return p1
   107  }
   108  
   109  //----------
   110  
   111  // maxColorDiff in [0.0, 1.0]
   112  func PaintShadow(img draw.Image, r image.Rectangle, height int, maxColorDiff float64) {
   113  	fn := func(c color.Color, v float64) color.Color {
   114  		//return Shade(c, v)
   115  		// paint shadow only if already rgba (allows noticing if not using RGBA colors)
   116  		if c2, ok := c.(color.RGBA); ok {
   117  			return shade(c2, v)
   118  		}
   119  		return c
   120  	}
   121  
   122  	step := 0
   123  	dy := float64(height)
   124  	for y := r.Min.Y; y < r.Max.Y; y++ {
   125  		yperc := float64(step) / dy
   126  		step++
   127  
   128  		//v := maxColorDiff * (1 - yperc)
   129  
   130  		// -(1/log(2))*log(x+1)+1
   131  		u := -(1/math.Log(2))*math.Log(yperc+1) + 1
   132  		v := maxColorDiff * u
   133  
   134  		for x := r.Min.X; x < r.Max.X; x++ {
   135  			atc := img.At(x, y)
   136  			c := fn(atc, v)
   137  			img.Set(x, y, c)
   138  		}
   139  	}
   140  }