Ah, endianness issue, isn't it fun! BitBlt really operates on 32-bit words, so 4 pixels of your 8-bit form are stuffed into one word. And they are big-endian by default. You can indicate little-endian forms by using a negative depth. So, if you use -8 for your form depth it works.
You are (probably) on an x86 processor, which is little-endian, so your byte array's first byte ends up in the least significant byte of the first word. Interpreting that as a big-endian word gives the pattern you noticed. I should have mentioned that stuffing a byte array into a form is a hack (there is even a method Form>>hackBits:). It is a useful hack, see for example Bitmap>>asByteArray. But by looking at that method you see you need to pay attention to your CPU's endianness: Smalltalk isLittleEndian ==> true Your code could use this: Smalltalk isLittleEndian ifTrue: [form swapEndianness]. (or initialize its depth to 8 or -8 depending on endianness). The "proper" way would be to use a "bitPoker", which is independent of endianness, but considerably slower: | w h bytes form poker | w := 200. h := 200. bytes := ((1 to: w*h) collect: [:i | 255 ]) asByteArray. 1 to: w do: [ :x | 1 to: h do: [ :y | x = y ifTrue: [ bytes at: (w*(y - 1) + x) put: 0 ] ] ]. form := ColorForm extent: w@h depth: 8. form colors: ((0 to: 255) collect: [:i | Color gray: i / 255]). poker := BitBlt bitPokerToForm: form. 0 to: w-1 do: [ :x | 0 to: h-1 do: [ :y | poker pixelAt: x@y put: (bytes at: w * y + x + 1). ] ]. form display (Btw, don't put parens into "1 to: w do:". It works but defeats an important optimization). - Bert - On 12.06.2014, at 02:32, Sungjin Chun <chu...@castlesoft.co.kr> wrote: > Thanks you for your answer, however there is something I missed here. > > I've tried following code > > | w h bytes form | > w := 200. > h := 200. > bytes := ((1 to: w*h) collect: [:i | 255 ]) asByteArray. > (1 to: w) do: [ :x | > (1 to: h) do: [ :y | > x = y ifTrue: [ bytes at: (w*(y - 1) + x) put: 0 ] > ] > ]. > form := ColorForm extent: w@h depth: 8 bits: bytes. > form colors: ((0 to: 255) collect: [:i | Color gray: i / 255]). > form display > > What I expected is diagonal line but the result is not. What's wrong with my > code? > > Thank you in advance. > > > > On Wed, Jun 11, 2014 at 7:41 PM, Bert Freudenberg <b...@freudenbergs.de> > wrote: > On 11.06.2014, at 00:36, Sungjin Chun <chu...@castlesoft.co.kr> wrote: > > > Hi, > > > > I want to draw gray scale bitmap using byte array which has pixel by pixel > > gray > > scale value as byte like this; > > > > [0 0 0 0 0 0 0 0 > > 16 23 255 78 12 12 12 12 > > ... > > ...] (8x4 for example) > > > > I can draw this using Pen class pixel by pixel manner but this is very slow > > and > > I think there should be faster way of creating a Form using above byte > > array. > > If the width is a multiple of 4, you can use the byte array directly as form > bits: > > | w h bytes form | > w := 100. > h := 60. > bytes := ((1 to: w*h) collect: [:i | 256 atRandom - 1]) asByteArray. > form := ColorForm extent: w@h depth: 8 bits: bytes. > form colors: ((0 to: 255) collect: [:i | Color gray: i / 255]). > form display > > This would be the best and fastest way. If the width is not a multiple of 4 > then perhaps you can add the necessary padding when creating the byte array. > Otherwise, a very fast way is to use BitBlt to copy whole lines from the byte > array to the form. > > But even creating a byte array with the right padding just using at:put: > would be a lot faster than using a Pen. > > - Bert -
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners