Is there a way to set form colours using a 'fuzzy' option?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Is there a way to set form colours using a 'fuzzy' option?

Andy Burnett
I have an image with black text, and a white background. I would like to set the white pixels to transparent. I worked out how to do this, but of course it leaves me with a white halo around the text, where the border pixels are almost white, but not quite.

In googling about this, I discovered that RMagick has the idea of replacing pixels which are almost any particular colour. I didn't find anything similar in the ColorForm class. Is there a way to do this within Pharo?

Cheers
Andy
Reply | Threaded
Open this post in threaded view
|

Re: Is there a way to set form colours using a 'fuzzy' option?

Nicolai Hess-3-2
You can draw a new form with copybits and use your own color mapping.

First, I thought there would be a bitblt operation that you could use without explicit calculating the color mapping, a paint operation that would convert a gray-value to an alpha value. But I could find it.

In this special case (black text on white background) you can use an existing method for calculating this color map. This method is used by strike font to create apropriate glyph forms from its font bitmap. (A large bitmap with black characters on a white background.)

Here is an example that first, creates a form with black text on white background, and than computes the color map and copys the source form in a new form:

"create a test form "
sourceForm := Form extent: 300@150 depth: 32.
sourceForm fillColor: Color white.

"draw some black, bold text"
text := 'Hello World' asText.
text addAttribute: (TextFontReference toFont: (LogicalFont familyName: 'Source Sans Pro' pointSize: 32)).
text addAttribute: (TextColor color: Color black).
text addAttribute: (TextEmphasis bold).
text asMorph drawOn: sourceForm getCanvas.

"create a morph for displaying this form"
sourceImageMorph := ImageMorph withForm: sourceForm.
sourceImageMorph openInWorld; topLeft: 300@300.

"calculate the colormap"
colorMap := Color computeColorConvertingMap: Color black from: 32 to: 32 keepSubPixelAA: false.

"copy the source form bits to a new form of the same size"
newForm := sourceForm deepCopy copyBits: sourceForm boundingBox from: sourceForm at: 0@0 colorMap: (colorMap).

"create a morph for displaying this form"
newImageMorph := ImageMorph withForm: newForm.
newImageMorph openInWorld; topLeft: 300@500.







2017-12-27 22:43 GMT+01:00 Andy Burnett <[hidden email]>:
I have an image with black text, and a white background. I would like to set the white pixels to transparent. I worked out how to do this, but of course it leaves me with a white halo around the text, where the border pixels are almost white, but not quite.

In googling about this, I discovered that RMagick has the idea of replacing pixels which are almost any particular colour. I didn't find anything similar in the ColorForm class. Is there a way to do this within Pharo?

Cheers
Andy

Reply | Threaded
Open this post in threaded view
|

Re: Is there a way to set form colours using a 'fuzzy' option?

Andy Burnett
In reply to this post by Andy Burnett
Nicolai wrote
>>>

You can draw a new form with copybits and use your own color mapping.

First, I thought there would be a bitblt operation that you could use
without explicit calculating the color mapping, a paint operation that
would convert a gray-value to an alpha value. But I could find it.

In this special case (black text on white background) you can use an
existing method for calculating this color map. This method is used by
strike font to create apropriate glyph forms from its font bitmap. (A large
bitmap with black characters on a white background.)

Here is an example that first, creates a form with black text on white
background, and than computes the color map and copys the source form in a
new form:

"create a test form "
sourceForm := Form extent: 300@150 depth: 32.
sourceForm fillColor: Color white.

"draw some black, bold text"
text := 'Hello World' asText.
text addAttribute: (TextFontReference toFont: (LogicalFont familyName:
'Source Sans Pro' pointSize: 32)).
text addAttribute: (TextColor color: Color black).
text addAttribute: (TextEmphasis bold).
text asMorph drawOn: sourceForm getCanvas.

"create a morph for displaying this form"
sourceImageMorph := ImageMorph withForm: sourceForm.
sourceImageMorph openInWorld; topLeft: 300@300.

"calculate the colormap"
colorMap := Color computeColorConvertingMap: Color black from: 32 to: 32
keepSubPixelAA: false.

"copy the source form bits to a new form of the same size"
newForm := sourceForm deepCopy copyBits: sourceForm boundingBox from:
sourceForm at: 0@0 colorMap: (colorMap).

"create a morph for displaying this form"
newImageMorph := ImageMorph withForm: newForm.
newImageMorph openInWorld; topLeft: 300@500.

<<<

Thanks Nicolai
That is very helpful. However, I agree with you that this is probably something BitBlt should be able to handle. I have been looking at how they do this in mathematica, and they have some interesting approaches.

Cheers
Andy
Reply | Threaded
Open this post in threaded view
|

Re: Is there a way to set form colours using a 'fuzzy' option?

Stephane Ducasse-3
Nice I learned something :).
Stef

On Thu, Dec 28, 2017 at 11:42 PM, Andy Burnett
<[hidden email]> wrote:

> Nicolai wrote
>>>>
>
> You can draw a new form with copybits and use your own color mapping.
>
> First, I thought there would be a bitblt operation that you could use
> without explicit calculating the color mapping, a paint operation that
> would convert a gray-value to an alpha value. But I could find it.
>
> In this special case (black text on white background) you can use an
> existing method for calculating this color map. This method is used by
> strike font to create apropriate glyph forms from its font bitmap. (A large
> bitmap with black characters on a white background.)
>
> Here is an example that first, creates a form with black text on white
> background, and than computes the color map and copys the source form in a
> new form:
>
> "create a test form "
> sourceForm := Form extent: 300@150 depth: 32.
> sourceForm fillColor: Color white.
>
> "draw some black, bold text"
> text := 'Hello World' asText.
> text addAttribute: (TextFontReference toFont: (LogicalFont familyName:
> 'Source Sans Pro' pointSize: 32)).
> text addAttribute: (TextColor color: Color black).
> text addAttribute: (TextEmphasis bold).
> text asMorph drawOn: sourceForm getCanvas.
>
> "create a morph for displaying this form"
> sourceImageMorph := ImageMorph withForm: sourceForm.
> sourceImageMorph openInWorld; topLeft: 300@300.
>
> "calculate the colormap"
> colorMap := Color computeColorConvertingMap: Color black from: 32 to: 32
> keepSubPixelAA: false.
>
> "copy the source form bits to a new form of the same size"
> newForm := sourceForm deepCopy copyBits: sourceForm boundingBox from:
> sourceForm at: 0@0 colorMap: (colorMap).
>
> "create a morph for displaying this form"
> newImageMorph := ImageMorph withForm: newForm.
> newImageMorph openInWorld; topLeft: 300@500.
>
> <<<
>
> Thanks Nicolai
> That is very helpful. However, I agree with you that this is probably
> something BitBlt should be able to handle. I have been looking at how they
> do this in mathematica, and they have some interesting approaches.
>
> Cheers
> Andy