feat:提交
This commit is contained in:
176
tests/dev1/dataHandle/common/bmp.ts
Normal file
176
tests/dev1/dataHandle/common/bmp.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
const decoder = new TextDecoder()
|
||||
export class BmpDecoder {
|
||||
pos: number
|
||||
buffer: ArrayBuffer
|
||||
is_with_alpha: boolean
|
||||
bottom_up: boolean
|
||||
flag: string
|
||||
constructor(buffer: ArrayBuffer, is_with_alpha: boolean) {
|
||||
this.pos = 0
|
||||
this.buffer = buffer
|
||||
this.is_with_alpha = !!is_with_alpha
|
||||
this.bottom_up = true
|
||||
|
||||
this.flag = decoder.decode(this.buffer.slice(0, (this.pos += 2)))
|
||||
|
||||
if (this.flag != 'BM')
|
||||
throw new Error('Invalid BMP File')
|
||||
// this.parseHeader();
|
||||
// this.parseRGBA();
|
||||
}
|
||||
|
||||
parseHeader() {}
|
||||
parseRGBA() {}
|
||||
}
|
||||
|
||||
export function createBmpFile(
|
||||
imgData: ImageData,
|
||||
paramDic: { [key: string]: string } = {},
|
||||
) {
|
||||
let dpi = 300
|
||||
let bitPP = paramDic.bpp ? Number(paramDic.bpp) : 24
|
||||
let printResolution = Math.round(dpi * 39.3701)
|
||||
|
||||
if ([1, 24, 32].includes(bitPP) == false) {
|
||||
throw new Error(`不支持的${bitPP}bpp BMP`)
|
||||
}
|
||||
|
||||
let data = imgData.data
|
||||
|
||||
let width = imgData.width
|
||||
let height = imgData.height
|
||||
let extraBytes = width % 4
|
||||
let rgbSize = data.length
|
||||
switch (bitPP) {
|
||||
case 1:
|
||||
{
|
||||
let rowSize = width / 8 + (width % 8 > 0 ? 1 : 0)
|
||||
extraBytes = rowSize % 4
|
||||
rgbSize = height * (rowSize + extraBytes)
|
||||
}
|
||||
break
|
||||
case 24:
|
||||
{
|
||||
let rowSize = 3 * width
|
||||
extraBytes = rowSize % 4
|
||||
rgbSize = height * (rowSize + extraBytes)
|
||||
}
|
||||
break
|
||||
}
|
||||
let headerInfoSize = 40
|
||||
|
||||
/** ****************header */
|
||||
let flag = 'BM'
|
||||
let reserved = 0
|
||||
let offset = 54
|
||||
let fileSize = rgbSize + offset
|
||||
let planes = 1
|
||||
|
||||
let compress = 0
|
||||
let hr = printResolution
|
||||
let vr = printResolution
|
||||
let colors = 0
|
||||
let importantColors = 0
|
||||
let colorPaletteSize = 0
|
||||
if (bitPP == 1) {
|
||||
colorPaletteSize = 2 * 4
|
||||
}
|
||||
let buffer = new ArrayBuffer(offset + colorPaletteSize + rgbSize)
|
||||
let tempBuffer = new DataView(buffer)
|
||||
let pos = 0
|
||||
|
||||
// BMP Header
|
||||
// ID
|
||||
tempBuffer.setUint8(pos, flag.charCodeAt(0))
|
||||
pos += 1
|
||||
tempBuffer.setUint8(pos, flag.charCodeAt(1))
|
||||
pos += 1
|
||||
// size
|
||||
tempBuffer.setUint32(pos, fileSize, true)
|
||||
pos += 4
|
||||
|
||||
// Application specific
|
||||
tempBuffer.setUint32(pos, reserved, true)
|
||||
pos += 4
|
||||
// Offset
|
||||
tempBuffer.setUint32(pos, offset, true)
|
||||
pos += 4
|
||||
|
||||
// DIB Header
|
||||
// Number of bytes in the DIB header (from this point)
|
||||
tempBuffer.setUint32(pos, headerInfoSize, true)
|
||||
pos += 4
|
||||
|
||||
tempBuffer.setUint32(pos, width, true)
|
||||
pos += 4
|
||||
tempBuffer.setUint32(pos, height, true)
|
||||
pos += 4
|
||||
|
||||
tempBuffer.setUint16(pos, planes, true)
|
||||
pos += 2
|
||||
tempBuffer.setUint16(pos, bitPP, true)
|
||||
pos += 2
|
||||
|
||||
tempBuffer.setUint16(pos, compress, true)
|
||||
pos += 4
|
||||
|
||||
tempBuffer.setUint16(pos, rgbSize, true)
|
||||
pos += 4
|
||||
|
||||
tempBuffer.setUint16(pos, hr, true)
|
||||
pos += 4
|
||||
tempBuffer.setUint16(pos, vr, true)
|
||||
pos += 4
|
||||
|
||||
tempBuffer.setUint16(pos, colors, true)
|
||||
pos += 4
|
||||
tempBuffer.setUint16(pos, importantColors, true)
|
||||
pos += 4
|
||||
|
||||
if (bitPP == 1) {
|
||||
tempBuffer.setUint8(pos++, 0) // b
|
||||
tempBuffer.setUint8(pos++, 0) // g
|
||||
tempBuffer.setUint8(pos++, 0) // r
|
||||
tempBuffer.setUint8(pos++, 0) // a
|
||||
|
||||
tempBuffer.setUint8(pos++, 255) // b
|
||||
tempBuffer.setUint8(pos++, 255) // g
|
||||
tempBuffer.setUint8(pos++, 255) // r
|
||||
tempBuffer.setUint8(pos++, 0) // a
|
||||
}
|
||||
|
||||
let pixData = ''
|
||||
let writeBinData = () => {
|
||||
tempBuffer.setUint8(pos++, Number.parseInt(pixData.padEnd(8, '0'), 2))
|
||||
pixData = ''
|
||||
}
|
||||
for (let y = height - 1; y >= 0; y--) {
|
||||
let rowIndex = y * width * 4
|
||||
for (let x = 0; x < width; x++) {
|
||||
let p = rowIndex + x * 4
|
||||
|
||||
if (bitPP == 1) {
|
||||
if (pixData.length == 8) {
|
||||
writeBinData()
|
||||
}
|
||||
let rgb = [data[p + 0], data[p + 1], data[p + 2]]
|
||||
pixData += rgb.filter((v, i) => v > 170).length == 3 ? '1' : '0' // 170 以下小板缩略图条会断
|
||||
} else {
|
||||
tempBuffer.setUint8(pos++, data[p + 2]) // b
|
||||
tempBuffer.setUint8(pos++, data[p + 1]) // g
|
||||
tempBuffer.setUint8(pos++, data[p + 0]) // r
|
||||
if (bitPP == 32) {
|
||||
tempBuffer.setUint8(pos++, data[p + 3]) // a
|
||||
}
|
||||
}
|
||||
}
|
||||
if (bitPP == 1 && pixData.length > 0) {
|
||||
writeBinData()
|
||||
}
|
||||
for (let index = 0; index < extraBytes; index++) {
|
||||
tempBuffer.setUint8(pos++, 0)
|
||||
}
|
||||
}
|
||||
|
||||
return tempBuffer.buffer
|
||||
}
|
Reference in New Issue
Block a user