const fs = require("fs")
const PNG = require('pngjs').PNG;
function getPixelsSync(filename){
return new Promise(function (resolve,reject) {
fs.createReadStream(filename)
.pipe(new PNG({
filterType: 4
}))
.on('parsed', function() {
resolve(this)
});
})
}
function getMat(pixels){
const h=pixels.height;
const w=pixels.width;
const mat1=new Matrix([],h,w);
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const idx = (w * y + x) << 2;
mat1.setItem(y,x,[pixels.data[idx],pixels.data[idx+1],pixels.data[idx+2],pixels.data[idx+3]])
}
}
return mat1;
}
function setPixelsToPng(filename,pixels,mat){
const h=pixels.height;
const w=pixels.width;
for (let y = 0; y < h; y++) {
for (let x = 0; x < w; x++) {
const idx = (w * y + x) << 2;
const px=mat.getItem(y,x)
if(Array.isArray(px)){
pixels.data[idx]=px[0]
pixels.data[idx+1]=px[1]
pixels.data[idx+2]=px[2]
pixels.data[idx+3]=px[3]
}else{
pixels.data[idx]=undefined;
pixels.data[idx+1]=undefined
pixels.data[idx+2]=undefined
pixels.data[idx+3]=undefined
}
}
}
pixels.pack().pipe(fs.createWriteStream(filename));
}
const {Matrix,Fraction,Point,Line} = require("./utils/math");
//是不是直线
function isLine(pos,dre,num,mat){
const x=pos.x||pos[0];
const y=pos.y||pos[1];
const xd=dre.x||dre[0];
const yd=dre.y||dre[1];
let state=true;
const item1=mat.getItem(y,x);
const color1=item1?item1.toString():item1;
for(let i=1;i<num;i++){
const item2=mat.getItem(y+yd*i,x+xd*i);
const color2=item2?item2.toString():item2;
if(color1!==color2){
state=false;
break;
}
}
return state;
}
//找出line的长度
function findLine(pos,dre,mat){
const x=pos.x||pos[0];
const y=pos.y||pos[1];
const xd=dre.x||dre[0];
const yd=dre.y||dre[1];
const color1=mat.getItem(y,x).toString();
let i=0;
let go=true;
while (go) {
i++;
const item=mat.getItem(y+yd*i,x+xd*i)
if(!item||color1!==item.toString()){
go=false;
}
}
return i;
}
//找出角度
function findPosLine(mat){
let w=15;
let h=15;
let x=w;
let y=h;
const arr=[]
while (x<mat.Column-w&&y<mat.Row-h){
x++;
if(isLine([x,y],[1,0],w,mat)&&!isLine([x+1,y],[0,1],h,mat)){
if(isLine([x,y],[0,1],h,mat)&&!isLine([x,y+1],[1,0],w,mat)){
arr.push({x,y})
}
}
if(x===mat.Column-w){
x=w;
y++;
}
}
return arr;
}
function getRectArr(mat){
const yArr=[]
let obj;
let index=0;
let state=true;
for(let y=0;y<mat.Row;y++){
let yh=0;
for(let x=0;x<mat.Column;x++){
if(yh===0&&mat.getItem(y,x)===1){
yh=1;
}else if(yh===1&&mat.getItem(y,x)!==1){
}
}
if(state!==yh){
if(state){
obj=yArr[index]={y:y,h:1};
}else{
index++;
}
state=!state;
}else if(!state){
obj.h++;
}
}
const xArr=[]
index=0;
state=true;
for(let x=0;x<mat.Column;x++){
let xh=true;
for(let y=0;y<mat.Row;y++){
if(mat.getItem(y,x)===1){
xh=false;
break;
}
}
if(state!==xh){
if(state){
obj=xArr[index]={x:x,w:1};
}else{
index++;
}
state=!state;
}else if(!state){
obj.w++;
}
}
const rectArr=[]
xArr.forEach(function ({x,w}) {
yArr.forEach(function ({y,h}) {
rectArr.push({x,y,w,h})
})
})
return rectArr;
}
//清理颜色
function clearColor(pos,mat){
if(!mat.getItem(pos.y,pos.x)){
return;
}
const arr=[pos];
let index=0;
function isSame(pos1,pos2) {
const num=10;
let color1=mat.getItem(pos1.y,pos1.x);
let color2=mat.getItem(pos2.y,pos2.x);
if(color1&&color2){
return Math.abs(color1[0]-color2[0])<num&&Math.abs(color1[1]-color2[1])<num&&Math.abs(color1[2]-color2[2])<num&&Math.abs(color1[3]-color2[3])<num
}
return false;
}
while (index<arr.length){
const pos1=arr[index]
index++;
const {x,y}=pos1;
const pos2={y:y-1,x};
const pos3={y:y+1,x};
const pos4={y,x:x+1};
const pos5={y,x:x-1};
if(isSame(pos1,pos2)){
arr.push(pos2)
}
if(isSame(pos1,pos3)){
arr.push(pos3)
}
if(isSame(pos1,pos4)){
arr.push(pos4)
}
if(isSame(pos1,pos5)){
arr.push(pos5)
}
mat.setItem(y,x,null)
}
const nmat=new Matrix([],mat.Row,mat.Column)
arr.forEach(function ({x,y}) {
nmat.setItem(y,x,1)
})
return nmat;
}
//根据rect切割矩阵
async function init(filename,outfilename) {
let pixels=await getPixelsSync(filename);
console.log(pixels)
//1定义矩阵
const mat1=getMat(pixels);
//找到背景点
const arr=findPosLine(mat1)
arr.forEach(function (rect) {
const nmat=clearColor(rect,mat1)
if(nmat){
// const rectArr=getRectArr(nmat)
// console.log(rectArr)
// console.log(rectArr)
}
})
// console.log(findPosLine2(mat1))
// console.log(findPosLine3(mat1))
setPixelsToPng(outfilename,pixels,mat1)
}
init('2.png','out.png');