关于在JavaScript条码生成中添加Code 39 Full ASCII及解决条码过短问题的技术问询
Hey there! Let's get your barcode sorted out. The root issue here is that standard Code 39 only supports 43 characters (uppercase letters, digits, and a small set of symbols), so any characters outside that set get truncated or ignored—hence your short, incomplete barcode. Switching to Code 39 Full ASCII fixes this by using double-character escape sequences to represent the full ASCII table. Here's how to update your JavaScript implementation:
1. Replace the Character Mapping with Full ASCII Support
First, update the character-to-code mapping in barcode.js to include the full Code 39 Full ASCII set. This map converts every ASCII character to its corresponding Code 39 escape sequence:
// Add this to barcode.js (replace your existing Code 39 map) const code39FullAsciiMap = { '\x00': '%U', '\x01': '$A', '\x02': '$B', '\x03': '$C', '\x04': '$D', '\x05': '$E', '\x06': '$F', '\x07': '$G', '\x08': '$H', '\x09': '$I', '\x0A': '$J', '\x0B': '$K', '\x0C': '$L', '\x0D': '$M', '\x0E': '$N', '\x0F': '$O', '\x10': '$P', '\x11': '$Q', '\x12': '$R', '\x13': '$S', '\x14': '$T', '\x15': '$U', '\x16': '$V', '\x17': '$W', '\x18': '$X', '\x19': '$Y', '\x1A': '$Z', '\x1B': '%A', '\x1C': '%B', '\x1D': '%C', '\x1E': '%D', '\x1F': '%E', ' ': ' ', '!': '/A', '"': '/B', '#': '/C', '$': '/D', '%': '/E', '&': '/F', '\'': '/G', '(': '/H', ')': '/I', '*': '/J', '+': '/K', ',': '/L', '-': '-', '.': '/N', '/': '/O', '0': '0', '1': '1', '2': '2', '3': '3', '4': '4', '5': '5', '6': '6', '7': '7', '8': '8', '9': '9', ':': '/Z', ';': '%F', '<': '%G', '=': '%H', '>': '%I', '?': '%J', '@': '%V', 'A': 'A', 'B': 'B', 'C': 'C', 'D': 'D', 'E': 'E', 'F': 'F', 'G': 'G', 'H': 'H', 'I': 'I', 'J': 'J', 'K': 'K', 'L': 'L', 'M': 'M', 'N': 'N', 'O': 'O', 'P': 'P', 'Q': 'Q', 'R': 'R', 'S': 'S', 'T': 'T', 'U': 'U', 'V': 'V', 'W': 'W', 'X': 'X', 'Y': 'Y', 'Z': 'Z', '[': '%K', '\\': '%L', ']': '%M', '^': '%N', '_': '%O', '`': '%W', 'a': '+A', 'b': '+B', 'c': '+C', 'd': '+D', 'e': '+E', 'f': '+F', 'g': '+G', 'h': '+H', 'i': '+I', 'j': '+J', 'k': '+K', 'l': '+L', 'm': '+M', 'n': '+N', 'o': '+O', 'p': '+P', 'q': '+Q', 'r': '+R', 's': '+S', 't': '+T', 'u': '+U', 'v': '+V', 'w': '+W', 'x': '+X', 'y': '+Y', 'z': '+Z', '{': '%P', '|': '%Q', '}': '%R', '~': '%S' }; // Keep your existing standard Code 39 pattern map (for encoding the escaped characters) const code39Patterns = { '0': '101001101101', '1': '110100101011', '2': '101100101011', '3': '110110010101', '4': '101001101011', '5': '110100110101', '6': '101100110101', '7': '101001011011', '8': '110100101101', '9': '101100101101', 'A': '110101001011', 'B': '101101001011', 'C': '110110100101', 'D': '101011001011', 'E': '110101100101', 'F': '101101100101', 'G': '101010011011', 'H': '110101001101', 'I': '101101001101', 'J': '101011001101', 'K': '110101010011', 'L': '101101010011', 'M': '110110101001', 'N': '101011010011', 'O': '110101101001', 'P': '101101101001', 'Q': '101010110011', 'R': '110101011001', 'S': '101101011001', 'T': '101011011001', 'U': '110010101011', 'V': '100110101011', 'W': '110011010101', 'X': '100101101011', 'Y': '110010110101', 'Z': '100110110101', '-': '100101011011', '.': '110010101101', ' ': '100110101101', '$': '100100100101', '/': '100100101001', '+': '100101001001', '%': '101001001001', '*': '101001101011' // Start/stop character };
2. Add a Conversion Function to Handle Full ASCII Input
In script.js, add a function that converts your raw input text into the Code 39 Full ASCII escaped sequence (including required start/stop * characters):
function convertToFullAsciiCode39(inputText) { let encodedSequence = ''; for (const char of inputText) { const escapedChar = code39FullAsciiMap[char]; if (!escapedChar) { throw new Error(`Unsupported character in input: "${char}" (ASCII code ${char.charCodeAt(0)})`); } encodedSequence += escapedChar; } // Wrap with start/stop markers (mandatory for Code 39) return `*${encodedSequence}*`; }
3. Update Barcode Generation to Support Longer Sequences
Your short barcode issue is likely because your current code uses a fixed width instead of calculating width dynamically based on the encoded sequence. Modify the barcode drawing logic in barcode.js to compute total width dynamically:
function drawBarcode(canvasId, encodedText) { const canvas = document.getElementById(canvasId); const ctx = canvas.getContext('2d'); const narrowWidth = 2; // Adjust based on your desired barcode size const wideWidth = narrowWidth * 3; // Code 39 uses 3x width for wide bars/spaces let xPos = 10; // Starting X position const yPos = 10; const barHeight = 50; // Clear canvas first ctx.clearRect(0, 0, canvas.width, canvas.height); for (const char of encodedText) { const pattern = code39Patterns[char]; if (!pattern) continue; // Draw each bar/space in the character pattern for (const bit of pattern) { const width = bit === '1' ? narrowWidth : wideWidth; ctx.fillStyle = bit === '1' ? '#000' : '#fff'; ctx.fillRect(xPos, yPos, width, barHeight); xPos += width; } // Add space between characters ctx.fillStyle = '#fff'; ctx.fillRect(xPos, yPos, narrowWidth, barHeight); xPos += narrowWidth; } // Update canvas width to fit the full barcode canvas.width = xPos + 10; }
4. Test the Implementation
Call these functions in your script to generate the full barcode:
// Example usage const input = "Hello World! 123@abc"; try { const encoded = convertToFullAsciiCode39(input); drawBarcode('barcodeCanvas', encoded); } catch (err) { console.error(err.message); }
Make sure to test with characters that previously failed (like lowercase letters, symbols, or special ASCII characters) to confirm the barcode now includes all content.
内容的提问来源于stack exchange,提问作者Jay Melbourne

