123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- /* eslint-disable */
- const HAS_ALPHA = true
- function scale(scale, input, output, inputRemovable) {
- if (!input) {
- input = scale.input
- output = scale.output
- inputRemovable = scale.inputRemovable
- if (scale.scale) scale = scale.scale
- }
- var canvas, ctx
- if (input.src) {
- canvas = document.createElement('canvas')
- if (input.naturalWidth != null) {
- canvas.width = input.naturalWidth
- canvas.height = input.naturalHeight
- } else if (input.runtimeStyle != null) {
- var runtimeStyle = input.runtimeStyle
- , mw = runtimeStyle.width, mh = runtimeStyle.height
- runtimeStyle.width = 'auto'
- runtimeStyle.height = 'auto'
- canvas.width = input.width
- canvas.height = input.height
- runtimeStyle.width = mw
- runtimeStyle.height = mh
- } else {
- var mw = input.width, mh = input.height
- if (input.removeAttribute) {
- input.removeAttribute('width')
- input.removeAttribute('height')
- }
- canvas.width = input.width
- canvas.height = input.height
- input.width = mw
- input.height = mh
- }
- } else {
- canvas = input
- }
- ctx = canvas.getContext('2d')
- if (input.src) ctx.drawImage(input, 0, 0)
- var sw = canvas.width, sh = canvas.height
- , dw, dh
- , sourceBuffer = ctx.getImageData(0, 0, sw, sh).data
- if (!sw || !sh) return false
- if (input.src || inputRemovable) {
- ctx.clearRect(0, 0, sw, sh)
- }
- if (typeof scale === 'object') {
- if (scale.width) {
- dw = scale.width + 0.5 | 0
- dh = scale.height + 0.5 | 0
- } else {
- dw = sw * scale.scaleX + 0.5 | 0
- dh = sh * scale.scaleY + 0.5 | 0
- }
- } else {
- dw = scale * sw + 0.5 | 0
- dh = scale * sh + 0.5 | 0
- }
- var dw4 = dw << 2
- , sw4 = sw << 2
- , sx, sy, sindex = 0
- , dx, dy, dyindex, dindex = 0
- , idx, idy, isx, isy
- , w, wx, nwx, wy, nwy
- , crossX, crossY
- , dwh4 = dw4 * dh
- , tmpBuffer
- , r, g, b, a
- , dsy, dsx
- , newCanvas, newCtx, imageData, byteBuffer
- , TIMES = 255.99 / 255
- , row0, row1, row2, row3
- , col0, col1, col2, col3
- , scaleX = dw / sw
- , scaleY = dh / sh
- , scaleXY = scaleX * scaleY
- function setNewCanvas() {
- // CREATE downscale canvas
- if (typeof output === 'object') {
- newCanvas = output
- } else if (input.src || inputRemovable) {
- newCanvas = canvas
- } else {
- newCanvas = document.createElement('canvas')
- }
- newCanvas.width = dw
- newCanvas.height = dh
- newCtx = newCanvas.getContext('2d')
- }
- function getImageData(tmpBuffer) {
- if (!tmpBuffer) {
- return newCtx.getImageData(0, 0, dw, dh)
- } else {
- var imageData = newCtx.getImageData(0, 0, dw, dh)
- , byteBuffer = imageData.data
- , dindex
- for (dindex = 0; dindex < dwh4; dindex += 4) {
- byteBuffer[dindex] = tmpBuffer[dindex] * TIMES | 0
- byteBuffer[dindex + 1] = tmpBuffer[dindex + 1] * TIMES | 0
- byteBuffer[dindex + 2] = tmpBuffer[dindex + 2] * TIMES | 0
- byteBuffer[dindex + 3] = HAS_ALPHA ? tmpBuffer[dindex + 3] * TIMES | 0 : 255
- }
- // delete tmpBuffer
- return imageData
- }
- }
- if (scaleX > 1 || scaleY > 1) {
- // UPSCALE by bicubic
- function bicubic(t, a, b, c, d) {
- return 0.5 * (c - a + (2 * a - 5 * b + 4 * c - d + (3 * (b - c) + d - a) * t) * t) * t + b
- }
- setNewCanvas()
- imageData = getImageData()
- byteBuffer = imageData.data
- for (dy = 0; dy < dh; dy++) {
- sy = dy / scaleY
- isy = sy | 0
- dsy = sy - isy
- row1 = isy * sw4
- row0 = isy < 1 ? row1 : row1 - sw4
- if (isy < sh - 2) {
- row2 = row1 + sw4
- row3 = (isy + 2) * sw4
- } else {
- row2 = row3 = isy > sh - 2 ? row1 : row1 + sw4
- }
- for (dx = 0; dx < dw; dx++ , dindex += 4) {
- sx = dx / scaleX
- isx = sx | 0
- dsx = sx - isx
- col1 = isx << 2
- col0 = isx < 1 ? col1 : col1 - 4
- if (isx < sw - 2) {
- col2 = col1 + 4
- col3 = col1 + 8
- } else {
- col2 = col3 = isx > sw - 2 ? col1 : col1 + 4
- }
- // RED
- r = bicubic(dsy,
- bicubic(dsx
- , sourceBuffer[row0 + col0]
- , sourceBuffer[row0 + col1]
- , sourceBuffer[row0 + col2]
- , sourceBuffer[row0 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row1 + col0]
- , sourceBuffer[row1 + col1]
- , sourceBuffer[row1 + col2]
- , sourceBuffer[row1 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row2 + col0]
- , sourceBuffer[row2 + col1]
- , sourceBuffer[row2 + col2]
- , sourceBuffer[row2 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row3 + col0]
- , sourceBuffer[row3 + col1]
- , sourceBuffer[row3 + col2]
- , sourceBuffer[row3 + col3]
- )
- ) * TIMES | 0
- // GREEN
- ++col0, ++col1, ++col2, ++col3
- g = bicubic(dsy,
- bicubic(dsx
- , sourceBuffer[row0 + col0]
- , sourceBuffer[row0 + col1]
- , sourceBuffer[row0 + col2]
- , sourceBuffer[row0 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row1 + col0]
- , sourceBuffer[row1 + col1]
- , sourceBuffer[row1 + col2]
- , sourceBuffer[row1 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row2 + col0]
- , sourceBuffer[row2 + col1]
- , sourceBuffer[row2 + col2]
- , sourceBuffer[row2 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row3 + col0]
- , sourceBuffer[row3 + col1]
- , sourceBuffer[row3 + col2]
- , sourceBuffer[row3 + col3]
- )
- ) * TIMES | 0
- // BLUE
- ++col0, ++col1, ++col2, ++col3
- b = bicubic(dsy,
- bicubic(dsx
- , sourceBuffer[row0 + col0]
- , sourceBuffer[row0 + col1]
- , sourceBuffer[row0 + col2]
- , sourceBuffer[row0 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row1 + col0]
- , sourceBuffer[row1 + col1]
- , sourceBuffer[row1 + col2]
- , sourceBuffer[row1 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row2 + col0]
- , sourceBuffer[row2 + col1]
- , sourceBuffer[row2 + col2]
- , sourceBuffer[row2 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row3 + col0]
- , sourceBuffer[row3 + col1]
- , sourceBuffer[row3 + col2]
- , sourceBuffer[row3 + col3]
- )
- ) * TIMES | 0
- byteBuffer[dindex] = r >= 0 ? r < 256 ? r : 255 : 0
- byteBuffer[dindex + 1] = g >= 0 ? g < 256 ? g : 255 : 0
- byteBuffer[dindex + 2] = b >= 0 ? b < 256 ? b : 255 : 0
- if (HAS_ALPHA) {
- // ALPHA
- ++col0, ++col1, ++col2, ++col3
- a = bicubic(dsy,
- bicubic(dsx
- , sourceBuffer[row0 + col0]
- , sourceBuffer[row0 + col1]
- , sourceBuffer[row0 + col2]
- , sourceBuffer[row0 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row1 + col0]
- , sourceBuffer[row1 + col1]
- , sourceBuffer[row1 + col2]
- , sourceBuffer[row1 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row2 + col0]
- , sourceBuffer[row2 + col1]
- , sourceBuffer[row2 + col2]
- , sourceBuffer[row2 + col3]
- )
- , bicubic(dsx
- , sourceBuffer[row3 + col0]
- , sourceBuffer[row3 + col1]
- , sourceBuffer[row3 + col2]
- , sourceBuffer[row3 + col3]
- )
- ) * TIMES | 0
- byteBuffer[dindex + 3] = a >= 0 ? a < 256 ? a : 255 : 0
- } else {
- byteBuffer[dindex + 3] = 255
- }
- }
- }
- } else {
- // DOWNSCALE
- if (root.Float32Array) {
- tmpBuffer = new Float32Array(dwh4)
- } else {
- tmpBuffer = []
- for (dindex = 0; dindex < dwh4; ++dindex) {
- tmpBuffer[dindex] = 0
- }
- }
- // CREATE float buffer
- for (sy = 0; sy < sh; sy++) {
- dy = sy * scaleY
- idy = dy | 0
- dyindex = idy * dw4
- crossY = (!!((idy - (dy + scaleY | 0)) * (sh - 1 - sy))) << 1
- if (crossY) {
- wy = idy + 1 - dy
- nwy = dy + scaleY - idy - 1
- }
- for (sx = 0; sx < sw; sx++ , sindex += 4) {
- dx = sx * scaleX
- idx = dx | 0
- dindex = dyindex + (idx << 2)
- crossX = !!((idx - (dx + scaleX | 0)) * (sw - 1 - sx))
- if (crossX) {
- wx = idx + 1 - dx
- nwx = dx + scaleX - idx - 1
- }
- r = sourceBuffer[sindex]
- g = sourceBuffer[sindex + 1]
- b = sourceBuffer[sindex + 2]
- if (HAS_ALPHA) a = sourceBuffer[sindex + 3]
- switch (crossX + crossY) {
- case 0:
- tmpBuffer[dindex] += r * scaleXY
- tmpBuffer[dindex + 1] += g * scaleXY
- tmpBuffer[dindex + 2] += b * scaleXY
- if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * scaleXY
- break
- case 1:
- w = wx * scaleY
- tmpBuffer[dindex] += r * w
- tmpBuffer[dindex + 1] += g * w
- tmpBuffer[dindex + 2] += b * w
- if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w
- w = nwx * scaleY
- tmpBuffer[dindex + 4] += r * w
- tmpBuffer[dindex + 5] += g * w
- tmpBuffer[dindex + 6] += b * w
- if (HAS_ALPHA) tmpBuffer[dindex + 7] += a * w
- break
- case 2:
- w = scaleX * wy
- tmpBuffer[dindex] += r * w
- tmpBuffer[dindex + 1] += g * w
- tmpBuffer[dindex + 2] += b * w
- if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w
- w = scaleX * nwy
- dindex += dw4
- tmpBuffer[dindex] += r * w
- tmpBuffer[dindex + 1] += g * w
- tmpBuffer[dindex + 2] += b * w
- if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w
- break
- default:
- w = wx * wy
- tmpBuffer[dindex] += r * w
- tmpBuffer[dindex + 1] += g * w
- tmpBuffer[dindex + 2] += b * w
- if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w
- w = nwx * wy
- tmpBuffer[dindex + 4] += r * w
- tmpBuffer[dindex + 5] += g * w
- tmpBuffer[dindex + 6] += b * w
- if (HAS_ALPHA) tmpBuffer[dindex + 7] += a * w
- w = wx * nwy
- dindex += dw4
- tmpBuffer[dindex] += r * w
- tmpBuffer[dindex + 1] += g * w
- tmpBuffer[dindex + 2] += b * w
- if (HAS_ALPHA) tmpBuffer[dindex + 3] += a * w
- w = nwx * nwy
- tmpBuffer[dindex + 4] += r * w
- tmpBuffer[dindex + 5] += g * w
- tmpBuffer[dindex + 6] += b * w
- if (HAS_ALPHA) tmpBuffer[dindex + 7] += a * w
- break
- }
- }
- }
- // delete sourceBuffer
- setNewCanvas()
- imageData = getImageData(tmpBuffer)
- }
- newCtx.putImageData(imageData, 0, 0)
- if (typeof output === 'string') {
- if (output === 'png' || output === 'jpeg') {
- var img
- if (inputRemovable && input.src) {
- img = input
- } else {
- img = new Image()
- }
- img.width = dw
- img.height = dh
- img.src = newCanvas.toDataURL('image/' + output, 1)
- return img
- } else if (output === 'png-src' || output === 'jpeg-src') {
- return newCanvas.toDataURL('image/' + output.split('-')[0], 1)
- }
- }
- return newCanvas
- }
- module.exports = scale;
|