Welcome Guest! You need to login or register to make posts.

Notification

Icon
Error

Options
Go to last post Go to first unread
CGbitmap  
#1 Posted : Friday, October 3, 2008 5:51:54 AM(UTC)
CGbitmap

Rank: Newbie

Groups: Member
Joined: 10/3/2008(UTC)
Posts: 3

Hello,

I am using Graphics Mill version 4.

My problem is I need to clamp all the data in CMYK channels to either 0 or 100%. So I copy the channel bitmap data to another bitmap object, do a levels color reduction, then copy the bitmap data into the appropriate channel in the CMYK image.

Code:

Dim channelData As New Aurigma.GraphicsMill.BitMap

channelData = image.Channels(Aurigma.GraphicsMill.ColorChannel.Black)
channelData.ColorAdjustment.Levels( _
    0.0, 1.0, 0.499999, 5.0, 0.500001, Aurigma.GraphicsMill.HistogramMode.Luminosity)
image.Channels(Aurigma.GraphicsMill.ColorChannel.Black) = channelData

channelData = image.Channels(Aurigma.GraphicsMill.ColorChannel.Yellow)
channelData.ColorAdjustment.Levels( _
    0.0, 1.0, 0.499999, 5.0, 0.500001, Aurigma.GraphicsMill.HistogramMode.Luminosity)
image.Channels(Aurigma.GraphicsMill.ColorChannel.Yellow) = channelData

channelData = image.Channels(Aurigma.GraphicsMill.ColorChannel.Magenta)
channelData.ColorAdjustment.Levels( _
    0.0, 1.0, 0.499999, 5.0, 0.500001, Aurigma.GraphicsMill.HistogramMode.Luminosity)
image.Channels(Aurigma.GraphicsMill.ColorChannel.Magenta) = channelData

channelData = image.Channels(Aurigma.GraphicsMill.ColorChannel.Cyan)
channelData.ColorAdjustment.Levels( _
    0.0, 1.0, 0.499999, 5.0, 0.500001, Aurigma.GraphicsMill.HistogramMode.Luminosity)
image.Channels(Aurigma.GraphicsMill.ColorChannel.Cyan) = channelData

This works pretty good, but the Levels ColorAdjustment *always* applies a FloydSteinberg dither, which gives little stray pixels across the image that wouldn't be there it I normally just clamp all the pixel values based on 0 <= .5 > 1.0

A simple Threshold filter will give me what I am looking for.

Is this possible in version 4 without iterating through all the pixel data manually?

Thanks for your response.

Edited by moderator Monday, May 28, 2012 8:35:36 PM(UTC)  | Reason: Not specified

Dmitry  
#2 Posted : Monday, October 6, 2008 2:52:56 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
Hello,

This functionality is not available in Graphics Mill but you can easily implement it. All you need is to copy pixels from on bitmap into another one applying threshold. The article Accessing Pixel Data will help you to implement this functionality.

Edited by user Tuesday, October 28, 2008 6:21:27 AM(UTC)  | Reason: Not specified

Sincerely yours,

Dmitry Sevostyanov

UserPostedImage Follow Aurigma on Twitter!

CGbitmap  
#3 Posted : Tuesday, October 7, 2008 4:13:38 AM(UTC)
CGbitmap

Rank: Newbie

Groups: Member
Joined: 10/3/2008(UTC)
Posts: 3

Thank you for the tip. This works much better than I had originally guessed it would perform.
CGbitmap  
#4 Posted : Wednesday, October 8, 2008 11:00:17 AM(UTC)
CGbitmap

Rank: Newbie

Groups: Member
Joined: 10/3/2008(UTC)
Posts: 3

In the interest of giving back to the forum, here is the subroutine that I made to do a threshold filter per your suggestion. Note that this subroutine assumes a 8bppGrayScale bitmap. I did it this way because I am processing individual CMYK channels. With a bit of work, this threshold subroutine could be modified to work on any bitmap.

Code:
    Public Sub ApplyThreshold(ByRef bitmap As Aurigma.GraphicsMill.Bitmap, ByVal threshold As Integer)

        ' Get and lock the raw data for the bitmap
        Dim data As Aurigma.GraphicsMill.BitmapData = bitmap.LockBits()

        ' How many bytes one pixel occupies
        Dim pixelSize As Integer = data.BitsPerPixel / 8

        ' Number of bytes in a row
        Dim stride As Integer = data.Stride

        ' Number of rows
        Dim height As Integer = data.Height

        ' Pointer to the beginning of the pixel data region
        Dim pointer As IntPtr = data.Scan0

        ' Array to represent a single pixel
        Dim pixel(pixelSize - 1) As Byte

        Dim i, j As Integer
        For i = 0 To height - 1
            j = 0
            Do While j < stride
                ' Read a single pixel
                Marshal.Copy(pointer, pixel, 0, pixelSize)
                ' Now modify the pixel, in this case clamp to 0 or max based on the threshold value
                If pixel(0) > threshold Then
                    pixel(0) = 255
                Else
                    pixel(0) = 0
                End If

                ' Write back the pixel data
                Marshal.Copy(pixel, 0, pointer, pixelSize)

                ' Compute the memory location of the next pixel
                pointer = IntPtr.op_Explicit(pointer.ToInt32 + pixelSize)
                j = j + pixelSize
            Loop
        Next i

        bitmap.UnlockBits(data)

    End Sub

Edited by user Tuesday, October 28, 2008 6:21:05 AM(UTC)  | Reason: Not specified

Dmitry  
#5 Posted : Wednesday, October 8, 2008 10:13:01 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
Thank you very much for your sample. I move this post to Knowledge base.
Sincerely yours,

Dmitry Sevostyanov

UserPostedImage Follow Aurigma on Twitter!

Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.