mirror of
https://github.com/lospec/pixel-editor.git
synced 2023-08-10 21:12:51 +03:00
Merge pull request #107 from Lattay/support_hex_palette
Implement importing GIMP and .hex palettes.
This commit is contained in:
commit
d9bde9bee6
@ -388,10 +388,12 @@ const ColorModule = (() => {
|
||||
*
|
||||
* @param {*} paletteColors The colours of the palette
|
||||
*/
|
||||
function createColorPalette(paletteColors) {
|
||||
function createColorPalette(paletteColors, clearCurrent=true) {
|
||||
//remove current palette
|
||||
while (colorsMenu.childElementCount > 1)
|
||||
colorsMenu.children[0].remove();
|
||||
if (clearCurrent) {
|
||||
while (colorsMenu.childElementCount > 1)
|
||||
colorsMenu.children[0].remove();
|
||||
}
|
||||
|
||||
var lightestColor = new Color("hex", '#000000');
|
||||
var darkestColor = new Color("hex", '#ffffff');
|
||||
@ -527,4 +529,4 @@ const ColorModule = (() => {
|
||||
updateCurrentColor,
|
||||
getSelectedColor,
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
@ -292,57 +292,143 @@ const FileManager = (() => {
|
||||
|
||||
return JSON.stringify(dictionary);
|
||||
}
|
||||
|
||||
let fromMenu = false;
|
||||
|
||||
function openImportPaletteWindow() {
|
||||
fromMenu = true;
|
||||
document.getElementById('load-palette-browse-holder').click();
|
||||
}
|
||||
|
||||
function loadPalette() {
|
||||
if (browsePaletteHolder.files && browsePaletteHolder.files[0]) {
|
||||
//make sure file is allowed filetype
|
||||
var fileContentType = browsePaletteHolder.files[0].type;
|
||||
if (fileContentType == 'image/png' || fileContentType == 'image/gif') {
|
||||
let file = browsePaletteHolder.files[0];
|
||||
var fileContentType =
|
||||
file.type
|
||||
|| file.name.split('.').slice(-1)[0];
|
||||
|
||||
//load file
|
||||
var fileReader = new FileReader();
|
||||
fileReader.onload = function(e) {
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
|
||||
//draw image onto the temporary canvas
|
||||
var loadPaletteCanvas = document.getElementById('load-palette-canvas-holder');
|
||||
var loadPaletteContext = loadPaletteCanvas.getContext('2d');
|
||||
|
||||
loadPaletteCanvas.width = img.width;
|
||||
loadPaletteCanvas.height = img.height;
|
||||
|
||||
loadPaletteContext.drawImage(img, 0, 0);
|
||||
|
||||
//create array to hold found colors
|
||||
var colorPalette = [];
|
||||
var imagePixelData = loadPaletteContext.getImageData(0,0,this.width, this.height).data;
|
||||
|
||||
//loop through pixels looking for colors to add to palette
|
||||
for (var i = 0; i < imagePixelData.length; i += 4) {
|
||||
const newColor = {r:imagePixelData[i],g:imagePixelData[i + 1],b:imagePixelData[i + 2]};
|
||||
var color = '#' + Color.rgbToHex(newColor);
|
||||
if (colorPalette.indexOf(color) == -1) {
|
||||
colorPalette.push(color);
|
||||
}
|
||||
}
|
||||
|
||||
//add to palettes so that it can be loaded when they click okay
|
||||
palettes['Loaded palette'] = {};
|
||||
palettes['Loaded palette'].colors = colorPalette;
|
||||
Util.setText('palette-button', 'Loaded palette');
|
||||
Util.setText('palette-button-splash', 'Loaded palette');
|
||||
Util.toggle('palette-menu-splash');
|
||||
};
|
||||
img.src = e.target.result;
|
||||
};
|
||||
var fileReader = new FileReader();
|
||||
|
||||
// dispatch on file type
|
||||
switch (fileContentType) {
|
||||
case 'image/png':
|
||||
case 'image/gif':
|
||||
fileReader.onload = loadPaletteFromImage;
|
||||
fileReader.readAsDataURL(browsePaletteHolder.files[0]);
|
||||
break;
|
||||
case 'gpl':
|
||||
fileReader.onload = loadPaletteFromGimp;
|
||||
fileReader.readAsText(browsePaletteHolder.files[0]);
|
||||
break;
|
||||
case 'hex':
|
||||
fileReader.onload = loadPaletteFromHex;
|
||||
fileReader.readAsText(browsePaletteHolder.files[0]);
|
||||
break;
|
||||
default:
|
||||
alert('Only PNG, GIF, .hex and .gpl files are supported at this time.');
|
||||
}
|
||||
else alert('Only PNG and GIF files are supported at this time.');
|
||||
}
|
||||
|
||||
browsePaletteHolder.value = null;
|
||||
}
|
||||
|
||||
function addPalette(colors) {
|
||||
if (fromMenu) {
|
||||
ColorModule.createColorPalette(colors, clearCurrent=false);
|
||||
} else {
|
||||
// From splash screen
|
||||
// add to palettes so that it can be loaded when they click okay
|
||||
palettes['Loaded palette'] = {};
|
||||
palettes['Loaded palette'].colors = colors;
|
||||
Util.setText('palette-button', 'Loaded palette');
|
||||
Util.setText('palette-button-splash', 'Loaded palette');
|
||||
Util.toggle('palette-menu-splash');
|
||||
}
|
||||
}
|
||||
|
||||
function loadPaletteFromImage(e) {
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
//draw image onto the temporary canvas
|
||||
var loadPaletteCanvas = document.getElementById('load-palette-canvas-holder');
|
||||
var loadPaletteContext = loadPaletteCanvas.getContext('2d');
|
||||
|
||||
loadPaletteCanvas.width = img.width;
|
||||
loadPaletteCanvas.height = img.height;
|
||||
|
||||
loadPaletteContext.drawImage(img, 0, 0);
|
||||
|
||||
//create array to hold found colors
|
||||
var colorPalette = [];
|
||||
var imagePixelData = loadPaletteContext.getImageData(0,0,this.width, this.height).data;
|
||||
|
||||
//loop through pixels looking for colors to add to palette
|
||||
for (var i = 0; i < imagePixelData.length; i += 4) {
|
||||
const newColor = {r:imagePixelData[i],g:imagePixelData[i + 1],b:imagePixelData[i + 2]};
|
||||
var color = '#' + Color.rgbToHex(newColor);
|
||||
if (colorPalette.indexOf(color) == -1) {
|
||||
colorPalette.push(color);
|
||||
}
|
||||
}
|
||||
|
||||
addPalette(colorPalette);
|
||||
};
|
||||
img.src = e.target.result;
|
||||
}
|
||||
|
||||
function loadPaletteFromGimp(e) {
|
||||
let content = e.target.result;
|
||||
let colorPalette = content.split(/\r?\n/)
|
||||
// Skip header line
|
||||
.slice(1)
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line != "")
|
||||
// discard comment lines
|
||||
.filter((line) => !line.startsWith('#'))
|
||||
// discard meta data lines
|
||||
.filter((line) => !line.includes(':'))
|
||||
.map((line) => {
|
||||
let components = line.split(/\s+/);
|
||||
|
||||
if (components.length < 3) {
|
||||
alert(`Invalid color specification ${line}.`);
|
||||
return "#000000"
|
||||
}
|
||||
|
||||
let [r, g, b, ...rest] = components;
|
||||
let color = {
|
||||
r: parseInt(r),
|
||||
g: parseInt(g),
|
||||
b: parseInt(b),
|
||||
};
|
||||
|
||||
if (isNaN(color.r) || isNaN(color.g) || isNaN(color.b)) {
|
||||
alert(`Invalid color specification ${line}.`);
|
||||
return "#000000"
|
||||
}
|
||||
|
||||
return '#' + Color.rgbToHex(color);
|
||||
});
|
||||
addPalette(colorPalette);
|
||||
}
|
||||
|
||||
function loadPaletteFromHex(e) {
|
||||
let content = e.target.result;
|
||||
let colorPalette = content.split(/\r?\n/)
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line != "")
|
||||
// discard comment lines
|
||||
.filter((line) => !line.startsWith('#'))
|
||||
.map((line) => {
|
||||
if (line.match(/[0-9A-Fa-f]{6}/)) {
|
||||
return '#' + line;
|
||||
}
|
||||
alert(`Invalid hex color ${line}.`);
|
||||
return '#000000';
|
||||
});
|
||||
addPalette(colorPalette);
|
||||
}
|
||||
|
||||
currentImportPivotElement = undefined;
|
||||
currentImportPivotPosition = 'middle';
|
||||
isImportWindowInitialized = false;
|
||||
@ -513,6 +599,7 @@ const FileManager = (() => {
|
||||
openPixelExportWindow,
|
||||
openSaveProjectWindow,
|
||||
openImportImageWindow,
|
||||
openImportPaletteWindow,
|
||||
open
|
||||
}
|
||||
|
||||
@ -526,4 +613,4 @@ const FileManager = (() => {
|
||||
}
|
||||
})
|
||||
return ret;
|
||||
})();
|
||||
})();
|
||||
|
@ -46,6 +46,9 @@ const TopMenuModule = (() => {
|
||||
case 'Import':
|
||||
Events.on('click', currSubmenuButton, FileManager.openImportImageWindow);
|
||||
break;
|
||||
case 'Load palette':
|
||||
Events.on('click', currSubmenuButton, FileManager.openImportPaletteWindow);
|
||||
break;
|
||||
case 'Export':
|
||||
Events.on('click', currSubmenuButton, FileManager.openPixelExportWindow);
|
||||
break;
|
||||
@ -139,4 +142,4 @@ const TopMenuModule = (() => {
|
||||
addInfoElement,
|
||||
resetInfos
|
||||
}
|
||||
})();
|
||||
})();
|
||||
|
@ -2,7 +2,7 @@
|
||||
<a id="save-image-link-holder" href="#">dl</a>
|
||||
<a id="save-project-link-holder" href="#">dl</a>
|
||||
<input id="open-image-browse-holder" type="file" accept="image/png, image/gif, .lpe" />
|
||||
<input id="load-palette-browse-holder" type="file" accept="image/png, image/gif" />
|
||||
<input id="load-palette-browse-holder" type="file" accept="image/png, image/gif, .gpl, .hex" />
|
||||
<input id="import-image-browse-holder" type="file" accept="image/png" />
|
||||
<canvas id="load-palette-canvas-holder"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -7,6 +7,7 @@
|
||||
<li><button>Save project</button></li>
|
||||
<li><button>Open</button></li>
|
||||
<li><button>Import</button></li>
|
||||
<li><button>Load palette</button></li>
|
||||
<li><button id="export-button" class="disabled">Export</button></li>
|
||||
<li><a href="https://lospec.com/pixel-editor">Exit</a></li>
|
||||
</ul>
|
||||
@ -74,4 +75,4 @@
|
||||
<li>{{> checkbox}}</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</ul>
|
||||
|
Loading…
Reference in New Issue
Block a user