Динамически генерировать прозрачный пиксель отслеживания - PullRequest
8 голосов
/ 28 декабря 2010

Я пытаюсь динамически генерировать четкий пиксель отслеживания в Java, но сталкиваюсь с некоторыми проблемами. У меня нет проблем с возвратом пользователю, но я не могу понять, какой пиксель правильный. Что я делаю не так?

Это то, что у меня есть, что дает мне 1x1 белый пиксель. Как сделать так, чтобы это было как можно меньше (размер файла) и сделать его прозрачным?

BufferedImage singlePixelImage = new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY_TYPE);
singlePixelImage.setRGB(0, 0, 0xFFFFFF);

Ответы [ 4 ]

11 голосов
/ 28 декабря 2010

Я считаю, что серый тип изображения не поддерживает прозрачность. Только модифицированный ответ Лукаша, чтобы точно показать, что происходит. Когда вы создаете новое изображение, все его пиксели имеют начальное значение, равное 0. Это означает, что оно полностью прозрачно. В следующем коде я делаю это явно:

    BufferedImage singlePixelImage = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
    Color transparent = new Color(0, 0, 0, 0);
    singlePixelImage.setRGB(0, 0, transparent.getRGB());

    File file = new File("pixel.png");
    try {
        ImageIO.write(singlePixelImage, "png", file);
    } catch (IOException e) {
        // TODO Auto-generated catch block
    }
3 голосов
/ 11 декабря 2012

Вот адаптация ответа @ Rekin для записи в байтовый массив вместо файла.

Отслеживаемое изображение, генерируемое динамически

public static byte[] get1x1PixelImage() throws IOException{

    // The following code was used to generate the tracking pixel.
    BufferedImage singlePixelImage = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
    Color transparent = new Color(0, 0, 0, 0);
    singlePixelImage.setRGB(0, 0, transparent.getRGB());

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(singlePixelImage, "png", baos);
    byte[] imageInBytes = baos.toByteArray();
    baos.close();

    return imageInBytes;
}

Получить статическое изображение отслеживания

// Use either format, tracking gif is smaller then the png.
static byte[] trackingGif = { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x1, 0x0, 0x1, 0x0, (byte) 0x80, 0x0, 0x0, (byte)  0xff, (byte)  0xff,  (byte) 0xff, 0x0, 0x0, 0x0, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x2, 0x2, 0x44, 0x1, 0x0, 0x3b };
static byte[] trackingPng = {(byte)0x89,0x50,0x4E,0x47,0x0D,0x0A,0x1A,0x0A,0x00,0x00,0x00,0x0D,0x49,0x48,0x44,0x52,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x08,0x06,0x00,0x00,0x00,0x1F,0x15,(byte)0xC4,(byte)0x89,0x00,0x00,0x00,0x0B,0x49,0x44,0x41,0x54,0x78,(byte)0xDA,0x63,0x60,0x00,0x02,0x00,0x00,0x05,0x00,0x01,(byte)0xE9,(byte)0xFA,(byte)0xDC,(byte)0xD8,0x00,0x00,0x00,0x00,0x49,0x45,0x4E,0x44,(byte)0xAE,0x42,0x60,(byte)0x82};

public static byte[] get1x1PixelImage() {
    return trackingGif;   // trackingGif is about 38 bytes where trackingPng is 68
}
2 голосов
/ 28 декабря 2010

Я думаю, что этого достаточно для создания BufferedImage с правильным типом.Нет необходимости вызывать метод setRGB.Попробуйте это:

BufferedImage singlePixelImage = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);

// then I'm saving the generated image in file:
File file = new File("pixel.png");
try {
   ImageIO.write(singlePixelImage, "png", file);
} catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
}

Я проверил файл pixel.png в Adobe PhotoShop, и он был прозрачным.

BufferedImage.TYPE_4BYTE_ABGR говорит добавить дополнительный четвертый байт, который хранит информацию об альфазначение канала (прозрачность пикселя).

1 голос
/ 28 декабря 2010

Если это пиксель отслеживания, зачем вам его каждый раз генерировать?Сгенерируйте его один раз, закодируйте как изображение GIF или PNG и отправьте только эти байты обратно клиенту HTTP.Это намного проще.

...