Codenameone 自动录制代号为1的图像
我需要在代码名1中自动录制图像。 Autocrop图像意味着从该图像中删除边框。下面代码的目的是搜索颜色(或透明度)相同的最大可能边界区域,然后从图像中裁剪该区域 为了更好地理解我写的算法,请考虑下面的图片(注意Topx、Topy、Butox、ButMy是谁): 这是我的密码。你能帮我弄明白什么地方出了问题并解决它吗?正如日志和屏幕截图所报告的,它没有按预期工作:Codenameone 自动录制代号为1的图像,codenameone,Codenameone,我需要在代码名1中自动录制图像。 Autocrop图像意味着从该图像中删除边框。下面代码的目的是搜索颜色(或透明度)相同的最大可能边界区域,然后从图像中裁剪该区域 为了更好地理解我写的算法,请考虑下面的图片(注意Topx、Topy、Butox、ButMy是谁): 这是我的密码。你能帮我弄明白什么地方出了问题并解决它吗?正如日志和屏幕截图所报告的,它没有按预期工作: Image arrowDownIcon = FontImage.createMaterial(FontImage.MATERIAL
Image arrowDownIcon = FontImage.createMaterial(FontImage.MATERIAL_ARROW_DROP_DOWN, "Color-Gray", 30);
Form hi = new Form("Hi World", new FlowLayout(Component.CENTER));
hi.getToolbar().hideToolbar();
hi.getContentPane().setUIID("NoMarginNoPadding");
hi.add(new Label(getAutoCroppedImage(arrowDownIcon), "NoMarginNoPadding"));
hi.show();
CSS
截图:
Image arrowDownIcon = FontImage.createMaterial(FontImage.MATERIAL_ARROW_DROP_DOWN, "Color-Gray", 30);
Form hi = new Form("Hi World", new FlowLayout(Component.CENTER));
hi.getToolbar().hideToolbar();
hi.getContentPane().setUIID("NoMarginNoPadding");
hi.add(new Label(getAutoCroppedImage(arrowDownIcon), "NoMarginNoPadding"));
hi.show();
您对基线颜色的期望与图像工作的实际情况不符。对于JPEG来说尤其如此,它可以有多种“白色”颜色,并且需要一个阈值。但在某种程度上,对于无损图像格式(如PNG)也是如此,其中alpha等值的行为可能“异常”,例如,有效的PNG文件可以返回0x00ffffff和0x0(两个像素),并且仍然有效 当绘图应用程序有一些透明的内容时,就会发生这种情况,大多数艺术家无法分辨其中的差别,并且应用程序不会丢弃那些不可见的数据。因此,您需要为alpha添加显式测试,例如:
if ((pixels[y * width + x] == baseColor || (pixels[y * width + x] & 0xff000000) == 0) {
...
}
给了我正确的提示。然而,我的代码还有另外两个错误:第一个错误是比较应该是color!=baseColor
而不是color==baseColor
;第二个是绘制新图像的参数应该是graphics.drawImage(source,-topx,-topy)代码>而不是我写的那些
在我的用例中,阈值是不必要的,但是对于任何想要实现它们的人,我建议使用代码名OneColorUtil
API而不是按位比较器来获得alpha、红色、绿色和蓝色,因为该API比按位比较器更具可读性和直观性
这是我的固定方法,我还添加了一个屏幕截图来演示它的工作原理:
/**
* Autocrop an image, using as base color the pixel at top left
*
* @param source
* @return
*/
public static Image getAutoCroppedImage(Image source) {
if (source == null) {
throw new IllegalArgumentException("ImageUtilities.getCroppedImage -> null source image");
}
if (source instanceof FontImage) {
source = ((FontImage) source).toImage();
}
int[] pixels = source.getRGB(); // array instance containing the ARGB data within this image
// Get top-left pixel color as "baseline" for cropping (it can be any color or transparent)
int baseColor = pixels[0];
int width = source.getWidth();
int height = source.getHeight();
int topy = 0;
int topx = 0;
int bottomy = height - 1;
int bottomx = width - 1;
// Search for topy, iterating the pixels from top to bottom
for (int y = 0; y < height && topy == 0; y++) {
for (int x = 0; x < width; x++) {
int color = pixels[y * width + x];
int alpha = ColorUtil.alpha(color);
if (color != baseColor && alpha != 0) {
topy = y;
break;
}
}
}
// Search for topx, interating the pixels from left to right
for (int x = 0; x < width && topx == 0; x++) {
for (int y = 0; y < height; y++) {
int color = pixels[y * width + x];
int alpha = ColorUtil.alpha(color);
if (color != baseColor && alpha != 0) {
topx = x;
break;
}
}
}
// Search for bottomy, iterating from bottom to top
for (int y = height - 1; y >= 0 && bottomy == height - 1; y--) {
for (int x = 0; x < width; x++) {
int color = pixels[y * width + x];
int alpha = ColorUtil.alpha(color);
if (color != baseColor && alpha != 0) {
bottomy = y;
break;
}
}
}
// Search for bottomx, interating from right to left
for (int x = width - 1; x >= 0 && bottomx == width - 1; x--) {
for (int y = 0; y < height; y++) {
int color = pixels[y * width + x];
int alpha = ColorUtil.alpha(color);
if (color != baseColor && alpha != 0) {
bottomx = x;
break;
}
}
}
Image destination = Image.createImage((bottomx - topx), (bottomy - topy), 0);
Log.p("Original width: " + width, Log.DEBUG);
Log.p("Original height: " + height, Log.DEBUG);
Log.p("Cropped width: " + destination.getWidth(), Log.DEBUG);
Log.p("Cropped height: " + destination.getHeight(), Log.DEBUG);
Log.p("Top-left point cropped image: (" + topx + "," + topy + ")", Log.DEBUG);
Log.p("Bottom-right point cropped image: (" + bottomx + "," + bottomy + ")", Log.DEBUG);
Graphics graphics = destination.getGraphics();
graphics.drawImage(source, -topx, -topy);
return destination;
}
/**
*使用左上角的像素作为底色自动拍摄图像
*
*@param源
*@返回
*/
公共静态图像getAutoCroppedImage(图像源){
if(source==null){
抛出新的IllegalArgumentException(“ImageUtilities.getCroppedImage->null源图像”);
}
if(FontImage的源实例){
source=((FontImage)source.toImage();
}
int[]pixels=source.getRGB();//包含此图像中的ARGB数据的数组实例
//获取左上角像素颜色作为裁剪的“基线”(可以是任何颜色或透明)
int baseColor=像素[0];
int width=source.getWidth();
int height=source.getHeight();
int-topy=0;
int-topx=0;
int bottomy=高度-1;
int bottomx=宽度-1;
//搜索topy,从上到下迭代像素
对于(int y=0;y=0&&bottomy==height-1;y--){
对于(int x=0;x=0&&bottomx==width-1;x--){
对于(int y=0;y
截图:
Image arrowDownIcon = FontImage.createMaterial(FontImage.MATERIAL_ARROW_DROP_DOWN, "Color-Gray", 30);
Form hi = new Form("Hi World", new FlowLayout(Component.CENTER));
hi.getToolbar().hideToolbar();
hi.getContentPane().setUIID("NoMarginNoPadding");
hi.add(new Label(getAutoCroppedImage(arrowDownIcon), "NoMarginNoPadding"));
hi.show();
谢谢你,谢了,你给了我正确的提示。我的代码也有其他错误:我添加了一个新的答案,并完全修复了代码,希望它能对其他人有用。我编辑了我的答案,修复了另一个错误。现在应该没事了。
/**
* Autocrop an image, using as base color the pixel at top left
*
* @param source
* @return
*/
public static Image getAutoCroppedImage(Image source) {
if (source == null) {
throw new IllegalArgumentException("ImageUtilities.getCroppedImage -> null source image");
}
if (source instanceof FontImage) {
source = ((FontImage) source).toImage();
}
int[] pixels = source.getRGB(); // array instance containing the ARGB data within this image
// Get top-left pixel color as "baseline" for cropping (it can be any color or transparent)
int baseColor = pixels[0];
int width = source.getWidth();
int height = source.getHeight();
int topy = 0;
int topx = 0;
int bottomy = height - 1;
int bottomx = width - 1;
// Search for topy, iterating the pixels from top to bottom
for (int y = 0; y < height && topy == 0; y++) {
for (int x = 0; x < width; x++) {
int color = pixels[y * width + x];
int alpha = ColorUtil.alpha(color);
if (color != baseColor && alpha != 0) {
topy = y;
break;
}
}
}
// Search for topx, interating the pixels from left to right
for (int x = 0; x < width && topx == 0; x++) {
for (int y = 0; y < height; y++) {
int color = pixels[y * width + x];
int alpha = ColorUtil.alpha(color);
if (color != baseColor && alpha != 0) {
topx = x;
break;
}
}
}
// Search for bottomy, iterating from bottom to top
for (int y = height - 1; y >= 0 && bottomy == height - 1; y--) {
for (int x = 0; x < width; x++) {
int color = pixels[y * width + x];
int alpha = ColorUtil.alpha(color);
if (color != baseColor && alpha != 0) {
bottomy = y;
break;
}
}
}
// Search for bottomx, interating from right to left
for (int x = width - 1; x >= 0 && bottomx == width - 1; x--) {
for (int y = 0; y < height; y++) {
int color = pixels[y * width + x];
int alpha = ColorUtil.alpha(color);
if (color != baseColor && alpha != 0) {
bottomx = x;
break;
}
}
}
Image destination = Image.createImage((bottomx - topx), (bottomy - topy), 0);
Log.p("Original width: " + width, Log.DEBUG);
Log.p("Original height: " + height, Log.DEBUG);
Log.p("Cropped width: " + destination.getWidth(), Log.DEBUG);
Log.p("Cropped height: " + destination.getHeight(), Log.DEBUG);
Log.p("Top-left point cropped image: (" + topx + "," + topy + ")", Log.DEBUG);
Log.p("Bottom-right point cropped image: (" + bottomx + "," + bottomy + ")", Log.DEBUG);
Graphics graphics = destination.getGraphics();
graphics.drawImage(source, -topx, -topy);
return destination;
}