yyman001 / blog

日常疑问记录解答
5 stars 0 forks source link

裁剪图所在原图的坐标 #33

Open yyman001 opened 6 years ago

yyman001 commented 6 years ago
function removeImageBlanks(imageObject) {
  let imgWidth = imageObject.width;
  let imgHeight = imageObject.height;
  var canvas = document.createElement("canvas");
  canvas.setAttribute("width", imgWidth);
  canvas.setAttribute("height", imgHeight);
  var context = canvas.getContext("2d");
  context.drawImage(imageObject, 0, 0);

  var imageData = context.getImageData(0, 0, imgWidth, imgHeight),
    data = imageData.data,
    getRBG = function(x, y) {
      var offset = imgWidth * y + x;
      return {
        red: data[offset * 4],
        green: data[offset * 4 + 1],
        blue: data[offset * 4 + 2],
        opacity: data[offset * 4 + 3]
      };
    },
    isWhite = function(rgb) {
      // console.log('rgb--',rgb)
      // many images contain noise, as the white is not a pure #fff white
      return rgb.red > 200 && rgb.green > 200 && rgb.blue > 200;
    },
    isTransparent = function(rgba){
       return rgba.opacity === 0
    },
    scanY = function(fromTop) {
      var offset = fromTop ? 1 : -1;

      // loop through each row
      for (
        var y = fromTop ? 0 : imgHeight - 1;
        fromTop ? y < imgHeight : y > -1;
        y += offset
      ) {
        // loop through each column
        for (var x = 0; x < imgWidth; x++) {
          var rgb = getRBG(x, y);
          if (!isWhite(rgb) && !isTransparent(rgb)) {
            if (fromTop) {
              return y;
            } else {
              return Math.min(y + 1, imgHeight - 1);
            }
          }
        }
      }
      return null; // all image is white
    },
    scanX = function(fromLeft) {
      var offset = fromLeft ? 1 : -1;

      // loop through each column
      for (
        var x = fromLeft ? 0 : imgWidth - 1;
        fromLeft ? x < imgWidth : x > -1;
        x += offset
      ) {
        // loop through each row
        for (var y = 0; y < imgHeight; y++) {
          var rgb = getRBG(x, y);
          if (!isWhite(rgb) && !isTransparent(rgb)) {
            if (fromLeft) {
              return x;
            } else {
              return Math.min(x + 1, imgWidth - 1);
            }
          }
        }
      }
      return null; // all image is white
    };

  var cropTop = scanY(true),
    cropBottom = scanY(false),
    cropLeft = scanX(true),
    cropRight = scanX(false),
    cropWidth = cropRight - cropLeft,
    cropHeight = cropBottom - cropTop;
  console.log(
    "cropTop:",
    cropTop,
    cropBottom,
    "cropLeft:",
    cropLeft,
    cropRight,
    cropWidth,
    cropHeight
  );
  canvas.setAttribute("width", cropWidth);
  canvas.setAttribute("height", cropHeight);
  // finally crop the guy
  canvas
    .getContext("2d")
    .drawImage(
      imageObject,
      cropLeft,
      cropTop,
      cropWidth,
      cropHeight,
      0,
      0,
      cropWidth,
      cropHeight
    );

  return canvas.toDataURL();
}
yyman001 commented 6 years ago

使用node jimp 处理图片,并生成裁剪后的图片

var path = require("path")

var Jimp = require("jimp");

let test_img = 'test/n2.png'
// open a file called "lenna.png"
// Jimp.read(test_img, function (err, lenna) {
//     if (err) throw err;
//     lenna
//          .autocrop(0.0003, false, function(){ console.log('callback') })
//          .write("test/render.png"); // save
// });

// image.getBuffer( mime, cb )
// image.getBase64( mime, cb )
// image.getPixelIndex(x, y);

// todo 
// 生成图片配置文件json [原图片信息-尺寸大小/裁剪后的坐标信息,以及大小]

// 批量读取图片
// 批量裁剪生成图片

Jimp.read(test_img).then(function (image) {
    // do stuff with the image
    let post = {}

        let data = image.bitmap.data,
        imgWidth = image.bitmap.width,
        imgHeight = image.bitmap.height,
        getRBG = function(x, y) {
          var offset = imgWidth * y + x;
          return {
            red: data[offset * 4],
            green: data[offset * 4 + 1],
            blue: data[offset * 4 + 2],
            opacity: data[offset * 4 + 3]
          };
        },
        isWhite = function(rgb) {
          // many images contain noise, as the white is not a pure #fff white
          return rgb.red > 200 && rgb.green > 200 && rgb.blue > 200;
        },
        isTransparent = function(rgba){
           return rgba.opacity === 0
        },
        scanY = function(fromTop) {
          var offset = fromTop ? 1 : -1;

          // loop through each row
          for (
            var y = fromTop ? 0 : imgHeight - 1;
            fromTop ? y < imgHeight : y > -1;
            y += offset
          ) {
            // loop through each column
            for (var x = 0; x < imgWidth; x++) {
              var rgb = getRBG(x, y);
              if (!isWhite(rgb) && !isTransparent(rgb)) {
                if (fromTop) {
                  return y;
                } else {
                  return Math.min(y + 1, imgHeight - 1);
                }
              }
            }
          }
          return null; // all image is white
        },
        scanX = function(fromLeft) {
          var offset = fromLeft ? 1 : -1;

          // loop through each column
          for (
            var x = fromLeft ? 0 : imgWidth - 1;
            fromLeft ? x < imgWidth : x > -1;
            x += offset
          ) {
            // loop through each row
            for (var y = 0; y < imgHeight; y++) {
              var rgb = getRBG(x, y);
              if (!isWhite(rgb) && !isTransparent(rgb)) {
                if (fromLeft) {
                  return x;
                } else {
                  return Math.min(x + 1, imgWidth - 1);
                }
              }
            }
          }
          return null; // all image is white
        };

        var cropTop = scanY(true),
            cropBottom = scanY(false),
            cropLeft = scanX(true),
            cropRight = scanX(false),
            cropWidth = cropRight - cropLeft,
            cropHeight = cropBottom - cropTop;

            post.top = cropTop;
            post.left = cropLeft;
            post.right = cropRight;
            post.bottom = cropBottom;
            post.width = cropWidth;
            post.height = cropHeight;

        console.log(
            "cropTop:",
            cropTop,
            'cropBottom:',
            cropBottom,
            "cropLeft:",
            cropLeft,
            'cropRight:',
            cropRight,
            'cropWidth:',cropWidth,
            'cropHeight:',cropHeight
        );
        // 拷贝对象生成裁剪图片
        image.clone().crop(post.left,post.top, post.width,post.height)
        .write("test/1.png");
}).catch(function (err) {
    // handle an exception
    console.log('error:', err)
});
yyman001 commented 6 years ago

可以使用版本/生成配置会报错,具体不清,查了很多都没解决,暂时就这样


var fs = require('fs')

var path = require("path")

var Jimp = require("jimp")

let directory = 'test'

let dir = path.resolve(directory)

// image.getBuffer( mime, cb )
// image.getBase64( mime, cb )
// image.getPixelIndex(x, y);
// image.getExtension() 后缀
// todo 
// 生成图片配置文件json [原图片信息-尺寸大小/裁剪后的坐标信息,以及大小]

// 批量读取图片
// 批量裁剪生成图片

var spriteJson = {
    name: '裁剪图片信息json',
    version: '1.0',
    sprite: []
}

var outputFilename = path.resolve(`${directory}/spriteMap.json`)

// 雪碧图信息
let spriteJsonArray = []

let imagesArray = []

// 记录扫描文件路径
let fileList = []

function walk(path) {
    var dirList = fs.readdirSync(path);

    dirList.forEach(function (item) {
        if (fs.statSync(path + '/' + item).isFile()) {
            fileList.push(path + '/' + item);
        }
    });

    dirList.forEach(function (item) {
        if (fs.statSync(path + '/' + item).isDirectory()) {
            walk(path + '/' + item);
        }
    });
}

walk(dir)

console.log(fileList);

// spritePath data => 'D:\\gulp\\test/top.png'
function cutSprite(spritePath) {
    return new Promise((resolve, reject) => {
        Jimp.read(spritePath).then(function (image) {
            // do stuff with the image
            let post = {}
            let path = spritePath.split('/')[0]

            post.name = spritePath.split('/').slice(-1)[0]
            post.outPutDir = path
            post.filePath = spritePath
            post.ow = image.bitmap.width
            post.oh = image.bitmap.height

            let data = image.bitmap.data,
                imgWidth = image.bitmap.width,
                imgHeight = image.bitmap.height,
                getRBG = function (x, y) {
                    var offset = imgWidth * y + x;
                    return {
                        red: data[offset * 4],
                        green: data[offset * 4 + 1],
                        blue: data[offset * 4 + 2],
                        opacity: data[offset * 4 + 3]
                    };
                },
                isWhite = function (rgb) {
                    // many images contain noise, as the white is not a pure #fff white
                    return rgb.red > 200 && rgb.green > 200 && rgb.blue > 200;
                },
                isTransparent = function (rgba) {
                    return rgba.opacity === 0
                },
                scanY = function (fromTop) {
                    var offset = fromTop ? 1 : -1;

                    // loop through each row
                    for (
                        var y = fromTop ? 0 : imgHeight - 1;
                        fromTop ? y < imgHeight : y > -1;
                        y += offset
                    ) {
                        // loop through each column
                        for (var x = 0; x < imgWidth; x++) {
                            var rgb = getRBG(x, y);
                            if (!isWhite(rgb) && !isTransparent(rgb)) {
                                if (fromTop) {
                                    return y;
                                } else {
                                    return Math.min(y + 1, imgHeight - 1);
                                }
                            }
                        }
                    }
                    return null; // all image is white
                },
                scanX = function (fromLeft) {
                    var offset = fromLeft ? 1 : -1;

                    // loop through each column
                    for (
                        var x = fromLeft ? 0 : imgWidth - 1;
                        fromLeft ? x < imgWidth : x > -1;
                        x += offset
                    ) {
                        // loop through each row
                        for (var y = 0; y < imgHeight; y++) {
                            var rgb = getRBG(x, y);
                            if (!isWhite(rgb) && !isTransparent(rgb)) {
                                if (fromLeft) {
                                    return x;
                                } else {
                                    return Math.min(x + 1, imgWidth - 1);
                                }
                            }
                        }
                    }
                    return null; // all image is white
                };

            var cropTop = scanY(true),
                cropBottom = scanY(false),
                cropLeft = scanX(true),
                cropRight = scanX(false),
                cropWidth = cropRight - cropLeft,
                cropHeight = cropBottom - cropTop

            post.top = cropTop
            post.left = cropLeft
            post.right = cropRight
            post.bottom = cropBottom
            post.width = cropWidth
            post.height = cropHeight

            console.log(
                post.name,
                "cropTop:",
                cropTop,
                'cropBottom:',
                cropBottom,
                "cropLeft:",
                cropLeft,
                'cropRight:',
                cropRight,
                'cropWidth:', cropWidth,
                'cropHeight:', cropHeight
            )

            spriteJsonArray.push(post)
            // 拷贝对象生成裁剪图片
            image.clone().crop(post.left, post.top, post.width, post.height)
                .write(`${post.outPutDir}/cut/${post.name}`)

            resolve(post)
        }).catch(function (err) {
            // handle an exception
            console.log('error:', err)
            reject(err)
        });
    })
}

// 判断文件是否存在
function hasFile(path) {
    return new Promise((resolve, reject) => {
        fs.stat(path, function (err, stat) {
            if (stat && stat.isFile()) {
                console.log('文件存在')
                resolve(true)
            } else {
                console.log('文件不存在或不是标准文件')
                resolve(false)
            }
        })
    })
}

//删除文件
function delFile(path) {
    return new Promise((resolve, reject) => {
        fs.unlink(path, function (err) {
            if (err) {
                reject()
            }
            console.log('文件删除成功')
            resolve(true)
        })
    })
}

// 删除文件夹及内容
function deleteall(path) {
    var files = [];
    if (fs.existsSync(path)) {
        files = fs.readdirSync(path);
        files.forEach(function (file, index) {
            var curPath = path + "/" + file;
            if (fs.statSync(curPath).isDirectory()) { // recurse  
                deleteall(curPath);
            } else { // delete file  
                fs.unlinkSync(curPath);
            }
        });
        fs.rmdirSync(path);
    } else {
    }
};

// 创建配置文件
function cearteMap() {
    fs.writeFileSync(outputFilename, JSON.stringify(spriteJson, null, 4), 'utf8', function (err) {
        if (err) {
            console.log('writeFileSync:', err)
        } else {
            console.log("生成配置文件:" + outputFilename)
        }
    })
}

let toCutSprite = async function () {
    let spriteInfoArray = fileList.slice()
    let temp = null
    console.log('/*****删除裁剪后的文件夹start*****/')
    deleteall(`${dir}/cut`)
    console.log('/*****删除裁剪后的文件夹end*****/')
    //判断旧的文件夹是否有配置文件,有就删除
    let has_map = await hasFile(outputFilename)

    if (has_map) {
        await delFile(outputFilename)
    }

    // for (let i = 0, length = spriteInfoArray.length; i < length; i++) {
    //     let data = await cutSprite(spriteInfoArray[i])
    // }
    console.log('/****开始裁剪图片*****/')
    while (spriteInfoArray.length) {
        temp = spriteInfoArray.shift()
        let result = await cutSprite(temp)
    }

    console.log('/******图片处理完毕!*******/')
    spriteJson.sprite = spriteJsonArray
    // bug 生成配置文件,如果存在再次生成会报错
    await cearteMap()
}

// 开始裁剪图片
toCutSprite()