readpixels dithering problem
Monkey Forums/Monkey Programming/readpixels dithering problem
| ||
![]() hello!~ This problem appears to be dithering. So I would like to find a workaround. Ask for advice. sorry... little english powered by google translator... |
| ||
Code example and what target? |
| ||
I'm guessing Android - it just seems to be a thing with some devices, they have low colour resolution and so they dither. I imagine there is no fix if you want to use ReadPixels with such devices except to use threshold values with the same low colour resolution. |
| ||
target for android my device is "lg optimus view 2" & "nexus s" image source = 32bit png file Function filter_dropShadow:Void(arr:Int[], _shadow1:Int, _shadow2:Int) For Local i:Int=0 To arr.Length-1 Local r : Int = ( arr[i] Shr 16 ) & $ff Local g : Int = ( arr[i] Shr 8 ) & $ff Local b : Int = arr[i] & $ff If r=0 And g=0 And b<34 arr[i] = (_shadow1 Shl 24)+(r Shl 16)+(g Shl 8)+b End If If r=0 And g<17 And b=0 arr[i] = (_shadow2 Shl 24)+(r Shl 16)+(g Shl 8)+b End If If r=0 And g=0 And b=0 arr[i] = 0 End If Next i End Function |
| ||
have a look on what Nobuyuki is doing here: http://monkeycoder.co.nz/Community/posts.php?topic=7702 He provides a method to read images before the device could dither them. And it works! Import mojo Import opengl.gles11 ..... Method GrabWithoutDither:Int[](FileName$) ' from: nDrawExts2, by Nobuyuki (nobu@...). Local data:Int[], info%[2] #If TARGET="android" Local db:DataBuffer = LoadImageData("monkey://data/" + FileName, info) Print "DATA BUFFER LENGTH= " + db.Length Local timeSpent:Int = Millisecs() 'Copy the data buffer into an array. data = data.Resize(db.Length / 4) '32-bits = 4 bytes 'We need to swap bytes of R and B channels around. For Local i:Int = 0 Until db.Length Step 4 Local j:Int = db.PeekInt(i) data[i / 4] = (j & $ff000000) | ((j & $00ff0000) Shr 16) | (j & $0000ff00) | ((j & $000000ff) Shl 16) Next Print "Operation took " + (Millisecs() -timeSpent) + "ms" #Endif Return data End |
| ||
to Midimaster thank you. but i see... it is different way. i want not dithering image from 'case by ReadPixels to WritePixels' |
| ||
maybe I misunderstood you... In your first post you wrote that the problem maybe caused by ReadPixels()? And in your second post you talk about an function which works with an array arr:Int[]. I guess this array contains the image datas. If you did create this array before your function with ReadPixels() it is now already damaged. Nobuyuki's way is a second possibility to create image arrays, but they are not damaged. You could work with an intact image data array... |
| ||
to Midimaster I know :) Thank you~ But I need to filter the ARGB. I wonder how the force dithering. Dithering 'on / off' is a way in monkey... |
| ||
In general, don't expect Android to be exact with these sorts of things. Dithering and low-colour palettes cause all sorts of issues, and Android Fragmentation makes everything that much worse. There are ways to request that the system doesn't do dithering, but given the chaos I've already seen, I wouldn't trust that it'll always work as expected. In short. Don't rely on readpixels. Avoid at all costs, or at the very least, expect it to be wrong most of the time. Unless you're comparing "really dark vs really light", don't attempt to use it. There's probably other ways to do what you're trying to do. |
| ||
I wrote a little module to force dithering off on android... Hold on a couple of minutes... |
| ||
After grabbing the image in Nobuyuki's way, you can filter the data as you like. It should be no problem... Do you want to manipulte image, which are avaiable as files? Or do you want to manipulate the current screen of your game? Dithering On/Off does not work on several devices. We tested this yesterday.... |
| ||
Here you go: http://www.subsoft.net/downloads/aglv05.zip Unzip to your module folder and import with Import agl Then you can: Field gl:AGL 'In Oncreate: gl = New AGL() 'In onrender, run this once: gl.DisableDithering(); By the way: Midimaster is right, not all devices support this... |
| ||
@sub_zero by the way, not related to the topic but related to AGL -- I'm pretty sure the mojo target on Android calls GlDisable(GL_BLEND) automatically whenever you call SetBlend(0). I say that because it was a pain in my behind figuring out why my custom blends weren't working on Android at first; calling SetBlend(1) first made it work because it calls GlEnable(GL_BLEND) :V |
| ||
Thank you many answers.:)![]() I want to like the picture attached. i need many pieces of tile. so can't like a Nobuyuki's source. I'm Going to find another way if a this idea. OTL |
| ||
Are you trying to make a drop shadow or a mask of some kind? I can try to help you, but I'm not sure I understand the diagram. It should be possible to do what you want, though. Edit: I saw your previous post. I'll try to help you later today! After I run some errands... |
| ||
@Nobuyuki: Yes I know :) This module wasn't made for release but the DisableDithering() method works :) |
| ||
@Pyongpyong Does it still give you dither problems with this? (using nDrawExts2......) The code above uses your filter_dropshadow() code. I don't know what it does, but you have some strange replacements in there that appear to be for replacing alpha. Here is code that might let you make a drop shadow a different way: Hope this helps~ |
| ||
sorry i'm busy to Sub_Zero Wow! I wanted it! Thank you very much:) to Nobuyuki I'm making a picture editor (17x16 tile-based). Outline of each layer was required to shadow effects. Each of the tiles to create a single image. So you can not use. That's really thoughtful of you. as a slight token of gratitude:) ![]() |
| ||
pyongpyong: Glad to be of any help :) |