Java 从BMP中提取附加数据

Java 从BMP中提取附加数据,java,bmp,steganography,Java,Bmp,Steganography,我想从BMP图像文件中提取附加数据 在我的函数中,所选BMP图像的数据流作为输入提供。在文件类型之后,我读取文件大小,然后需要迭代流的其余部分。附加数据被附加到BMP文件中,因此图像头中编码的文件大小不变 如何从文件大小字节数组中获取一个值,该值将确定在原始文件结束之前需要读取的字节数?(在添加数据之前,我需要迭代适当的字节数) 维基百科: 抵消 长度 描述 2. 4字节 BMP文件的大小(以字节为单位) 维基百科: 抵消 长度 描述 2. 4字节 BMP文件的大小(以字节为单位) 不要试图这样

我想从BMP图像文件中提取附加数据

在我的函数中,所选BMP图像的数据流作为输入提供。在文件类型之后,我读取文件大小,然后需要迭代流的其余部分。附加数据被附加到BMP文件中,因此图像头中编码的文件大小不变

如何从文件大小字节数组中获取一个值,该值将确定在原始文件结束之前需要读取的字节数?(在添加数据之前,我需要迭代适当的字节数)

维基百科:

抵消 长度 描述 2. 4字节 BMP文件的大小(以字节为单位) 维基百科:

抵消 长度 描述 2. 4字节 BMP文件的大小(以字节为单位)
不要试图这样做。此阵列的使用不是100%安全的。您可能会发现BMP文件大小错误。而是根据给定的分辨率、颜色深度和填充字节+标题大小+附加表格大小,自己计算估计的文件大小。不要尝试这样做。此阵列的使用不是100%安全的。您可能会发现BMP文件大小错误。而是使用给定的分辨率、颜色深度和填充字节+头大小+附加表大小,自己计算估计的文件大小。
private String getBMPAppendedData(DataInputStream in) {

        StringBuilder message = new StringBuilder();

        try {
            // Read the fileType : always 0x4d42 = "BM"
            in.readShort();
            // Read the file size
            byte[] fileSizeBytes = new byte[4];
            in.readFully(fileSizeBytes);

            // Read bytes in the loop 
            loop () {
            in.readByte();
            }

            // Read appended byte by byte if present
            boolean areSecretDataPresent = true;

            while (areSecretDataPresent) {
                try {

                    byte b = in.readByte();
                    message.append(String.format("%02X", b));

                } catch (Exception e) {

                    areSecretDataPresent = false;
                }
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }

        return message.toString();
    }
/**
 * Read an extra message, if it exists, from an InputStream containing a BMP image.
 *
 * @param is the InputStream to read from
 * @return the message found
 * @throws IOException if any exception other than EndOfFile is thrown after the BMP image
 */
private static String readExtraMessage(final InputStream is) throws IOException {
    final DataInputStream s = new DataInputStream(is);
    final byte b = 0x42; // 'B'
    final byte m = 0x4d; // 'M'
    final byte sig1 = s.readByte();
    final byte sig2 = s.readByte();
    if (!(sig1 == b && sig2 == m)) {
        throw new IllegalArgumentException("not a BMP file");
    }

    final byte[] fileSizeBuffer = new byte[4];
    s.readFully(fileSizeBuffer);
    final int fileSize = ByteBuffer.wrap(fileSizeBuffer, 0, 4).order(ByteOrder.LITTLE_ENDIAN).getInt();
    int bytesToSkip = fileSize - 6; // 2 byte for the signature, 4 bytes for the filesize.
    while (bytesToSkip > 0) {
        bytesToSkip -= s.skipBytes(bytesToSkip);
    }

    final StringBuilder buf = new StringBuilder();
    while (true) {
        try {
            final byte x = s.readByte();
            buf.append((char) x);
        } catch (final EOFException e) {
            break;
        }
    }

    return buf.toString();
}
/**
 * Read an extra message, if it exists, from a File containing a BMP image.
 *
 * @param f the File to read
 * @return the message found
 * @throws IOException if any exception is thrown while reading
 */
private static String readExtraMessage(final File f) throws IOException {
    final MappedByteBuffer mbb =
            FileChannel.open(f.toPath(), StandardOpenOption.READ).map(FileChannel.MapMode.READ_ONLY, 0, f.length());
    final byte B = 0x42;
    final byte M = 0x4d;
    if (!(mbb.get() == B && mbb.get() == M)) {
        throw new IllegalArgumentException("not a BMP file");
    }

    final int fileSize = mbb.order(ByteOrder.LITTLE_ENDIAN).getInt();
    if (fileSize == f.length()) {
        return "";
    }

    final ByteBuffer extra =  mbb.position(fileSize).slice();
    final byte[] messageBytes = new byte[extra.remaining()];
    extra.get(messageBytes);
    return new String(messageBytes);
}