我的问题如下:
我的问题是,即使在量化步骤之后进行LSB替换,我仍然会在检测端出现错误和变化。对于字符串,字母会被更改,但对于位图,图像不可读,因为从“参数无效”推断出。我已经尝试了很多调试,但我无法弄明白。
我的目标很简单,将一组位(在字符串或位图之前)插入到JPEG图像中,保存它并能够检测并将所述位集提取到其原始形式。我已经成功使用BMP和PNG,因为那里没有压缩,但JPEG是另一个故事。顺便说一句,我正在替换LSB。
我理解我需要做什么,在DCT系数量化后应用LSB替换。为此,我一直在使用JPEG编码器并在适当的位置修改我需要的内容。
我修改了方法EncodeImageBufferToJpg
以将字符串或位图转换为位数组(int []),然后对每个通道Y,Cb,Cr执行LSB替换为每个块的一个系数。
这是我修改的EncodeImageBufferToJpg
方法,加上我用来重建消息的Detection + Process方法:Link Here。
例如,对于Y频道:
在编码中:
Int16[] DCT_Quant_Y = Do_FDCT_Quantization_And_ZigZag(Y_Data, Tables.FDCT_Y_Quantization_Table);
if (!StegoEncodeDone)
{
// We clear the LSB to 0
DCT_Quant_Y[DCIndex] -= Convert.ToInt16(DCT_Quant_Y[DCIndex] % 2);
// We add the bit to the LSB
DCT_Quant_Y[DCIndex] += Convert.ToInt16(MsgBits[MsgIndx]);
// Ys for debug print
Ys.Add(DCT_Quant_Y[DCIndex]);
MsgIndx++;
if (MsgIndx >= MsgBits.Length) StegoEncodeDone = true;
}
DoHuffmanEncoding(DCT_Quant_Y, ref prev_DC_Y, Tables.Y_DC_Huffman_Table, Tables.Y_AC_Huffman_Table, OutputStream);
并且在检测中:
Int16[] DCT_Quant_Y = Do_FDCT_Quantization_And_ZigZag(Y_Data, Tables.FDCT_Y_Quantization_Table);
// SteganoDecode *********************************************
if (!StegoDecodeDone)
{
int Dtt = Math.Abs(DCT_Quant_Y[DCIndex] % 2);
int DYY = Y_Data[DCIndex];
int DDCTYYB = DCT_Quant_Y[DCIndex];
Ys.Add(DCT_Quant_Y[DCIndex]);
// Si le DCT Coefficient est negatif le % retournais un -1 mais binaire => 0,1 => positif
charValue = charValue * 2 + Math.Abs(DCT_Quant_Y[DCIndex] % 2);
ProcessStaganoDecode();
}
// End *********************************************************
DCT_Quant_Y.CopyTo(Y, index);
public void ProcessStaganoDecode()
{
Counter++;
cc++;
if (IDFound) MsgBits.Add(charValue % 2);
else IDBits.Add(charValue % 2);
if (Counter == 8)
{
// If we find a '-' we inc, else we set to 0. because they have to be 3 consecutive "---"
char ccs = (char)reverseBits(charValue);
if (((char)reverseBits(charValue)) == '-')
{
SepCounter++;
}
else SepCounter = 0;
if (SepCounter >= 3)
{
if (IDFound)
{
MsgBits.RemoveRange(MsgBits.Count - 3 * 8, 3 * 8);
StegoDecodeDone = MarqueFound = true;
}
else
{
IDFound = true;
IDBits.RemoveRange(IDBits.Count - 3 * 8, 3 * 8);
string ID = BitToString(IDBits);
IDNum = Convert.ToInt16(BitToString(IDBits));
Console.WriteLine("ID Found : " + IDNum);
}
SepCounter = 0;
}
charValue = 0;
Counter = 0;
}
}
所有代码都在课堂上:BaseJPEGEncoder
。
这是VS 2015 C#项目,您可以检查其余的类等。我只能放2个链接,所以抱歉无法放原版:Here。我从CodeProject的“C#中的简单JPEG编码器”中获得了原始编码器
我已经从这两个人的其他问题中读到了一些答案,如果可以的话,我很想引起他们的注意:Sneftel和Reti43。找不到联系他们的方法。