Click here to Skip to main content
15,909,324 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi Every One I try to Make Method that work To Hide Text into Image It works Fine in PNG and Gif Extensions but it's not work with jpg image here is the method i work with it Can any one Help me to make it work in Jpg Image Extensions
VB
Private Shared Sub HideOrExtract(ByRef messageStream As Stream, bitmap As Bitmap, keyStream As Stream, extract As Boolean, useGrayscale As Boolean)
            'Current count of pixels between two hidden message-bytes
            'Changes with every hidden byte according to the key
            Dim currentStepWidth As Integer = 0
            'Current byte in the key stream - normal direction
            Dim currentKeyByte As Byte
            'Current byte in the key stream - reverse direction
            Dim currentReverseKeyByte As Byte
            'current position in the key stream
            Dim keyPosition As Long

            'maximum X and Y position
            Dim bitmapWidth As Integer = bitmap.Width - 1
            Dim bitmapHeight As Integer = bitmap.Height - 1

            'Color component to hide the next byte in (0-R, 1-G, 2-B)
            'Rotates with every hidden byte
            Dim currentColorComponent As Integer = 0

            'Stores the color of a pixel
            Dim pixelColor As Color

            'Length of the message
            Dim messageLength As Int32

            If extract Then
                'Read the length of the hidden message from the first pixel
                pixelColor = bitmap.GetPixel(0, 0)
                messageLength = (pixelColor.R << 2) + (pixelColor.G << 1) + pixelColor.B
                messageStream = New MemoryStream(messageLength)
            Else

                messageLength = CType(messageStream.Length, Int32)

                If messageStream.Length >= 16777215 Then
                    'The message is too long
                    Dim exceptionMessage As String = "Themessage is too long, only 16777215 bytes are allowed."
                    Throw New Exception(exceptionMessage)
                End If

                'Check size of the carrier image

                
                Dim countPixels As Long = (bitmapWidth * bitmapHeight) - 1
                'Pixels required - start with one pixel for length of message
                Dim countRequiredPixels As Long = 1
                'add up the gaps between used pixels (sum up all the bytes of the key)
                While (keyStream.Position < keyStream.Length) AndAlso (keyStream.Position < messageLength)
                    countRequiredPixels += keyStream.ReadByte()
                End While
                'If the key is shorter than the message, it will be repeated again and again
                'عدد البيكسلس اللى ححتاجه عشان اعرف احفظ الرساله بتعتى
                countRequiredPixels *= CLng(Math.Truncate(System.Math.Ceiling((CSng(messageStream.Length) / CSng(keyStream.Length)))))

                If countRequiredPixels > countPixels Then
                    'The bitmap is too small
                    Dim exceptionMessage As String = "The image is too small for this message and key. " & countRequiredPixels & " pixels are required."
                    Throw New Exception(exceptionMessage)
                End If

                '=======================================================
                Dim colorValue As Integer = messageLength
                Dim red As Integer = colorValue >> 2
                colorValue -= red << 2
                Dim green As Integer = colorValue >> 1
                Dim blue As Integer = colorValue - (green << 1)
                pixelColor = Color.FromArgb(red, green, blue)
                bitmap.SetPixel(0, 0, pixelColor)
                '========================================================
            End If

            'Reset the streams
            keyStream.Seek(0, SeekOrigin.Begin)
            messageStream.Seek(0, SeekOrigin.Begin)

            'Current position in the carrier bitmap
            'Start with 1, because (0,0) contains the message's length
            Dim pixelPosition As New Point(1, 0)

            'Loop over the message and hide each byte
            For messageIndex As Integer = 0 To messageLength - 1

                'repeat the key, if it is shorter than the message
                If keyStream.Position = keyStream.Length Then
                    keyStream.Seek(0, SeekOrigin.Begin)
                End If
                'Get the next pixel-count from the key, use "1" if it's 0
                currentKeyByte = CByte(keyStream.ReadByte())
                currentStepWidth = If((currentKeyByte = 0), CByte(1), currentKeyByte)

                'jump to reverse-read position and read from the end of the stream
                keyPosition = keyStream.Position
                keyStream.Seek(-keyPosition, SeekOrigin.[End])
                currentReverseKeyByte = CByte(keyStream.ReadByte())
                'jump back to normal read position
                keyStream.Seek(keyPosition, SeekOrigin.Begin)

                'Perform line breaks, if current step is wider than the image
                While currentStepWidth > bitmapWidth
                    currentStepWidth -= bitmapWidth
                    pixelPosition.Y += 1
                End While

                'Move X-position
                If (bitmapWidth - pixelPosition.X) < currentStepWidth Then
                    pixelPosition.X = currentStepWidth - (bitmapWidth - pixelPosition.X)
                    pixelPosition.Y += 1
                Else
                    pixelPosition.X += currentStepWidth
                End If

                'Get color of the "clean" pixel
                pixelColor = bitmap.GetPixel(pixelPosition.X, pixelPosition.Y)

                If extract Then
                    'Extract the hidden message-byte from the color
                    Dim foundByte As Byte = CByte(currentReverseKeyByte Xor GetColorComponent(pixelColor, currentColorComponent))
                    messageStream.WriteByte(foundByte)
                    'Rotate color components

                    currentColorComponent = If((currentColorComponent = 2), 0, (currentColorComponent + 1))
                Else
                    'To add a bit of confusion, xor the byte with a byte read from the keyStream
                    Dim currentByte As Integer = messageStream.ReadByte() Xor currentReverseKeyByte

                    If useGrayscale Then
                        pixelColor = Color.FromArgb(currentByte, currentByte, currentByte)
                    Else
                        'Change one component of the color to the message-byte
                        SetColorComponent(pixelColor, currentColorComponent, currentByte)
                        'Rotate color components
                        currentColorComponent = If((currentColorComponent = 2), 0, (currentColorComponent + 1))
                    End If
                    bitmap.SetPixel(pixelPosition.X, pixelPosition.Y, pixelColor)
                End If
            Next

            'the stream will be closed by the calling method
            bitmap = Nothing
            keyStream = Nothing
        End Sub
Posted

1 solution

And it won't ever work in a JPG file.

PNG and GIF files use lossless compression, JPG is Lossy - which means that PNG and GIF images are stored exactly as the source image was, but compressed. JPG files aren't - they use a much more efficient compression algorithm which throws away information in order to compress it further without significant visual degradation of the image. For steganography, this is a disaster, s most of the "added" information is the first to be discarded.

Try it: Open a JPG, and save it in a new file. Repeat ten times. Compare the original and final versions. Now do that with a GIF and you will see what I mean.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900