Android Question How do I read YUVimage from camera Preview?

paulc91316

Member
Licensed User
Longtime User
Currently I'm using the cameraEX class to grab the preview image and process the center horizontal line to read barcodes (from the ZXing source). It works great albeit a little slow.

What I do is execute the function "PreviewImageToJpeg" (below) and then grab the center line. Convert it to B&W (get the Y value) and then adjust brightness and contrast to extract the bits (or bars).

The thing is all I really want is the YUVimage (which should be the Y frame followed by a 1/4 U frame and a 1/4 V frame). I tried to extract it from the routine below but all I get is an array of all 0 (zeros).

In fact if I could just get the center horizontal line that would even be better.

Any ideas?

'Converts a preview image formatted in YUV format to JPEG.
'Note that you should not save every preview image as it will slow down the whole process.
Public Sub PreviewImageToJpeg(data() As Byte, quality As Int) As Byte()
Dim size, previewFormat As Object
r.target = parameters
size = r.RunMethod("getPreviewSize")
previewFormat = r.RunMethod("getPreviewFormat")
r.target = size
Dim width = r.GetField("width"), height = r.GetField("height") As Int
Dim yuvImage As Object = r.CreateObject2("android.graphics.YuvImage", _
Array As Object(data, previewFormat, width, height, Null), _
Array As String("[B", "java.lang.int", "java.lang.int", "java.lang.int", "[I"))
r.target = yuvImage
Dim rect1 As Rect
rect1.Initialize(0, 0, r.RunMethod("getWidth"), r.RunMethod("getHeight"))
Dim out As OutputStream
out.InitializeToBytesArray(100)
r.RunMethod4("compressToJpeg", Array As Object(rect1, quality, out), _
Array As String("android.graphics.Rect", "java.lang.int", "java.io_OutputStream"))
Return out.ToBytesArray
End Sub
 

JordiCP

Expert
Licensed User
Longtime User
If I understood it right, there is a faster way to do it if you only need B&W pixels from a central line

If your preview resolution is for instance W_preview*H_preview, the preview event gives you an array of 1.5*W_preview*H_preview bytes (perhaps rotated respect to screen orientation)
The first W_preview*H_preview are precisely the Y, so no need to convert to JPEG and then B&W

Let's assume that the preview is W_preview*H_preview landscape and this orientation is ok for you
The central horizontal line starts at previewBytes(W_preview*(H_preview/2)).
The following W_preview bytes are the scan of the central line

B4X:
Dim k, yVal as int
Dim startCentralHoLine as int = W_preview*(H_preview/2)
for k=0 to W_preview-1    'from left to right
'for k=W_preview-1 to 0 step -1  'from right to left
    yVal = data(startCentralHorLine+k)
    if yVal<0 then yVal = yVal+256 ' the value contained will be treated as unsigned 
    ' need threshold to convert to B&W ?
    if yVal<=myThreshold then
        myCentralLineBW(k) = 0  'Black
    else
        myCentralLineBW(k) = 1    'White
    end if
next


if you need to scan vertically, do something similar

B4X:
Dim k, yVal as int
Dim startCentralVertLine as int = W_preview/2
for k=0 to H_preview-1    'read from top to down
'for k=h_preview-1 to 0 step -1   'read from down to top
    yVal = data(startCentralVertLine + k*W_preview)
    if yVal<0 then yVal = yVal+256 ' the value contained will be treated as unsigned 
    ' need threshold to convert to B&W ?
    if yVal<=myThreshold then
        myCentralLineBW(k) = 0  'Black
    else
        myCentralLineBW(k) = 1    'White
    end if
next




sorry if there are mistakes, I have not tested these lines, but it must be something similar
 
Upvote 0
Top