【问题标题】:org.eclipse.swt.SWTException: Unsupported color depthorg.eclipse.swt.SWTException:不支持的颜色深度
【发布时间】:2018-05-29 12:50:47
【问题描述】:

我创建了一个示例 SWT 应用程序。我正在将几张图片上传到应用程序中。我必须调整所有高于 16x16(宽度*高度)分辨率的图像的大小并将它们保存在单独的位置。

出于这个原因,我正在缩放图像并将缩放后的图像保存到我的目标位置。下面是我用来执行此操作的一段代码。

使用getImageData() 获取图像数据并保存我正在使用ImageLoader save() 方法。

final Image mySampleImage = ImageResizer.scaleImage(img, 16, 16);
final ImageLoader imageLoader = new ImageLoader();
imageLoader.data = new ImageData[] { mySampleImage.getImageData() };
final String fileExtension = inputImagePath.substring(inputImagePath.lastIndexOf(".") + 1);
if ("GIF".equalsIgnoreCase(fileExtension)) {
    imageLoader.save(outputImagePath, SWT.IMAGE_GIF);
} else if ("PNG".equalsIgnoreCase(fileExtension)) {
    imageLoader.save(outputImagePath, SWT.IMAGE_PNG);
}

ImageLoader imageLoader.save(outputImagePath, SWT.IMAGE_GIF); 在我尝试保存一些特定图像(GIF 或 PNG 格式)时抛出以下异常。

org.eclipse.swt.SWTException: Unsupported color depth
    at org.eclipse.swt.SWT.error(SWT.java:4533)
    at org.eclipse.swt.SWT.error(SWT.java:4448)
    at org.eclipse.swt.SWT.error(SWT.java:4419)
    at org.eclipse.swt.internal.image.GIFFileFormat.unloadIntoByteStream(GIFFileFormat.java:427)
    at org.eclipse.swt.internal.image.FileFormat.unloadIntoStream(FileFormat.java:124)
    at org.eclipse.swt.internal.image.FileFormat.save(FileFormat.java:112)
    at org.eclipse.swt.graphics.ImageLoader.save(ImageLoader.java:218)
    at org.eclipse.swt.graphics.ImageLoader.save(ImageLoader.java:259)
    at mainpackage.ImageResizer.resize(ImageResizer.java:55)
    at mainpackage.ImageResizer.main(ImageResizer.java:110)

如果有任何其他方法可以做同样的事情(或)有任何方法可以解决这个问题,请告诉我。

【问题讨论】:

  • GIF 保存将仅保存颜色深度为 1、4 或 8 且带有间接调色板的图像。如果您的 ImageResizer 正在生成其他格式,则必须对其进行转换。
  • @greg-449 谢谢你的信息。我目前只使用 2 种格式,即 GIF 和 PNG,并且基于文件类型 ImageResizer 将转换为相应的图像类型。它没有产生其他格式。
  • 这里的“格式”是指您提供给ImageLoaderImageData 中字段的确切值。您得到的例外是因为 ImageData.depth 字段的值不是 1、4 或 8。
  • @greg-449 我已经检查了我的缩放图像的图像数据深度,这是 32,这就是这个异常的原因。这种情况有什么解决方法吗?
  • 您必须修复调整大小以保持调色板和颜色深度,或者您必须编写代码将调整大小的图像转换回具有正确颜色深度的索引调色板图像 - 我不知道任何 SWT 代码可以做到这一点。

标签: java swt


【解决方案1】:

最后我通过参考这个现有的 eclipse 错误Unsupported color depth eclipse bug 得到了解决方案。 在下面的代码中,我创建了一个带有 RGB 值的 PaletteData 并更新了我的图像数据。

如果图像深度为 32 或更大,我的 updateImagedata() 方法将获取缩放后的图像并返回正确更新的 imageData。

private static ImageData updateImagedata(Image image) {
        ImageData data = image.getImageData();
        if (!data.palette.isDirect && data.depth <= 8)
            return data;

        // compute a histogram of color frequencies
        HashMap<RGB, ColorCounter> freq = new HashMap<>();
        int width = data.width;
        int[] pixels = new int[width];
        int[] maskPixels = new int[width];
        for (int y = 0, height = data.height; y < height; ++y) {
            data.getPixels(0, y, width, pixels, 0);
            for (int x = 0; x < width; ++x) {
                RGB rgb = data.palette.getRGB(pixels[x]);
                ColorCounter counter = (ColorCounter) freq.get(rgb);
                if (counter == null) {
                    counter = new ColorCounter();
                    counter.rgb = rgb;
                    freq.put(rgb, counter);
                }
                counter.count++;
            }
        }

        // sort colors by most frequently used
        ColorCounter[] counters = new ColorCounter[freq.size()];
        freq.values().toArray(counters);
        Arrays.sort(counters);

        // pick the most frequently used 256 (or fewer), and make a palette
        ImageData mask = null;
        if (data.transparentPixel != -1 || data.maskData != null) {
            mask = data.getTransparencyMask();
        }
        int n = Math.min(256, freq.size());
        RGB[] rgbs = new RGB[n + (mask != null ? 1 : 0)];
        for (int i = 0; i < n; ++i)
            rgbs[i] = counters[i].rgb;
        if (mask != null) {
            rgbs[rgbs.length - 1] = data.transparentPixel != -1 ? data.palette.getRGB(data.transparentPixel)
                    : new RGB(255, 255, 255);
        }
        PaletteData palette = new PaletteData(rgbs);

        ImageData newData = new ImageData(width, data.height, 8, palette);
        if (mask != null)
            newData.transparentPixel = rgbs.length - 1;
        for (int y = 0, height = data.height; y < height; ++y) {
            data.getPixels(0, y, width, pixels, 0);
            if (mask != null)
                mask.getPixels(0, y, width, maskPixels, 0);
            for (int x = 0; x < width; ++x) {
                if (mask != null && maskPixels[x] == 0) {
                    pixels[x] = rgbs.length - 1;
                } else {
                    RGB rgb = data.palette.getRGB(pixels[x]);
                    pixels[x] = closest(rgbs, n, rgb);
                }
            }
            newData.setPixels(0, y, width, pixels, 0);
        }
        return newData;
    }

找到最小索引:

static int closest(RGB[] rgbs, int n, RGB rgb) {
        int minDist = 256*256*3;
        int minIndex = 0;
        for (int i = 0; i < n; ++i) {
            RGB rgb2 = rgbs[i];
            int da = rgb2.red - rgb.red;
            int dg = rgb2.green - rgb.green;
            int db = rgb2.blue - rgb.blue;
            int dist = da*da + dg*dg + db*db;
            if (dist < minDist) {
                minDist = dist;
                minIndex = i;
            }
        }
        return minIndex;
    }

ColorCounter 类:

class ColorCounter implements Comparable<ColorCounter> {
    RGB rgb;
    int count;

    public int compareTo(ColorCounter o) {
        return o.count - count;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 2016-08-21
    • 1970-01-01
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-28
    相关资源
    最近更新 更多