浏览代码

Add functions for nearest-neighbor resize of NRGBA, NRGBA16.

jst 9 年前
父节点
当前提交
79dc2b616d
共有 1 个文件被更改,包括 86 次插入0 次删除
  1. 86
    0
      nearest.go

+ 86
- 0
nearest.go 查看文件

@@ -118,6 +118,45 @@ func nearestRGBA(in *image.RGBA, out *image.RGBA, scale float64, coeffs []bool,
118 118
 	}
119 119
 }
120 120
 
121
+func nearestNRGBA(in *image.NRGBA, out *image.NRGBA, scale float64, coeffs []bool, offset []int, filterLength int) {
122
+	newBounds := out.Bounds()
123
+	maxX := in.Bounds().Dx() - 1
124
+
125
+	for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
126
+		row := in.Pix[x*in.Stride:]
127
+		for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
128
+			var rgba [4]float32
129
+			var sum float32
130
+			start := offset[y]
131
+			ci := y * filterLength
132
+			for i := 0; i < filterLength; i++ {
133
+				if coeffs[ci+i] {
134
+					xi := start + i
135
+					switch {
136
+					case uint(xi) < uint(maxX):
137
+						xi *= 4
138
+					case xi >= maxX:
139
+						xi = 4 * maxX
140
+					default:
141
+						xi = 0
142
+					}
143
+					rgba[0] += float32(row[xi+0])
144
+					rgba[1] += float32(row[xi+1])
145
+					rgba[2] += float32(row[xi+2])
146
+					rgba[3] += float32(row[xi+3])
147
+					sum++
148
+				}
149
+			}
150
+
151
+			xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*4
152
+			out.Pix[xo+0] = floatToUint8(rgba[0] / sum)
153
+			out.Pix[xo+1] = floatToUint8(rgba[1] / sum)
154
+			out.Pix[xo+2] = floatToUint8(rgba[2] / sum)
155
+			out.Pix[xo+3] = floatToUint8(rgba[3] / sum)
156
+		}
157
+	}
158
+}
159
+
121 160
 func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
122 161
 	newBounds := out.Bounds()
123 162
 	maxX := in.Bounds().Dx() - 1
@@ -165,6 +204,53 @@ func nearestRGBA64(in *image.RGBA64, out *image.RGBA64, scale float64, coeffs []
165 204
 	}
166 205
 }
167 206
 
207
+func nearestNRGBA64(in *image.NRGBA64, out *image.NRGBA64, scale float64, coeffs []bool, offset []int, filterLength int) {
208
+	newBounds := out.Bounds()
209
+	maxX := in.Bounds().Dx() - 1
210
+
211
+	for x := newBounds.Min.X; x < newBounds.Max.X; x++ {
212
+		row := in.Pix[x*in.Stride:]
213
+		for y := newBounds.Min.Y; y < newBounds.Max.Y; y++ {
214
+			var rgba [4]float32
215
+			var sum float32
216
+			start := offset[y]
217
+			ci := y * filterLength
218
+			for i := 0; i < filterLength; i++ {
219
+				if coeffs[ci+i] {
220
+					xi := start + i
221
+					switch {
222
+					case uint(xi) < uint(maxX):
223
+						xi *= 8
224
+					case xi >= maxX:
225
+						xi = 8 * maxX
226
+					default:
227
+						xi = 0
228
+					}
229
+					rgba[0] += float32(uint16(row[xi+0])<<8 | uint16(row[xi+1]))
230
+					rgba[1] += float32(uint16(row[xi+2])<<8 | uint16(row[xi+3]))
231
+					rgba[2] += float32(uint16(row[xi+4])<<8 | uint16(row[xi+5]))
232
+					rgba[3] += float32(uint16(row[xi+6])<<8 | uint16(row[xi+7]))
233
+					sum++
234
+				}
235
+			}
236
+
237
+			xo := (y-newBounds.Min.Y)*out.Stride + (x-newBounds.Min.X)*8
238
+			value := floatToUint16(rgba[0] / sum)
239
+			out.Pix[xo+0] = uint8(value >> 8)
240
+			out.Pix[xo+1] = uint8(value)
241
+			value = floatToUint16(rgba[1] / sum)
242
+			out.Pix[xo+2] = uint8(value >> 8)
243
+			out.Pix[xo+3] = uint8(value)
244
+			value = floatToUint16(rgba[2] / sum)
245
+			out.Pix[xo+4] = uint8(value >> 8)
246
+			out.Pix[xo+5] = uint8(value)
247
+			value = floatToUint16(rgba[3] / sum)
248
+			out.Pix[xo+6] = uint8(value >> 8)
249
+			out.Pix[xo+7] = uint8(value)
250
+		}
251
+	}
252
+}
253
+
168 254
 func nearestGray(in *image.Gray, out *image.Gray, scale float64, coeffs []bool, offset []int, filterLength int) {
169 255
 	newBounds := out.Bounds()
170 256
 	maxX := in.Bounds().Dx() - 1