javascript - How to access image pixel data in react-native -
i have image loaded camera roll or other source, local one.
how can access pixel data map perform calculations or measurements?
there way of getting information using native modules, have android implementation @ moment. tested on rn 0.42.3. first of all, you'll need create native module in app. assuming application initialized name sampleapp
, create new directory in react native project android/app/src/main/java/com/sampleapp/bitmap
2 files in it:
android/app/src/main/java/com/sampleapp/bitmap/bitmapreactpackage.java
package com.sampleapp; import com.facebook.react.reactpackage; import com.facebook.react.bridge.javascriptmodule; import com.facebook.react.bridge.nativemodule; import com.facebook.react.bridge.reactapplicationcontext; import com.facebook.react.uimanager.viewmanager; import java.util.arraylist; import java.util.collections; import java.util.list; public class bitmapreactpackage implements reactpackage { @override public list<class<? extends javascriptmodule>> createjsmodules() { return collections.emptylist(); } @override public list<viewmanager> createviewmanagers(reactapplicationcontext reactcontext) { return collections.emptylist(); } @override public list<nativemodule> createnativemodules( reactapplicationcontext reactcontext) { list<nativemodule> modules = new arraylist<>(); modules.add(new bitmapmodule(reactcontext)); return modules; } }
android/app/src/main/java/com/sampleapp/bitmap/bitmapmodule.java
package com.sampleapp; import com.facebook.react.bridge.nativemodule; import com.facebook.react.bridge.reactapplicationcontext; import com.facebook.react.bridge.reactcontext; import com.facebook.react.bridge.reactcontextbasejavamodule; import com.facebook.react.bridge.reactmethod; import com.facebook.react.bridge.promise; import com.facebook.react.bridge.writablenativearray; import com.facebook.react.bridge.writablenativemap; import android.graphics.bitmap; import android.graphics.bitmapfactory; import java.io.ioexception; public class bitmapmodule extends reactcontextbasejavamodule { public bitmapmodule(reactapplicationcontext reactcontext) { super(reactcontext); } @override public string getname() { return "bitmap"; } @reactmethod public void getpixels(string filepath, final promise promise) { try { writablenativemap result = new writablenativemap(); writablenativearray pixels = new writablenativearray(); bitmap bitmap = bitmapfactory.decodefile(filepath); if (bitmap == null) { promise.reject("failed decode. path incorrect or image corrupted"); return; } int width = bitmap.getwidth(); int height = bitmap.getheight(); boolean hasalpha = bitmap.hasalpha(); (int x = 0; x < width; x++) { (int y = 0; y < height; y++) { int color = bitmap.getpixel(x, y); string hex = integer.tohexstring(color); pixels.pushstring(hex); } } result.putint("width", width); result.putint("height", height); result.putboolean("hasalpha", hasalpha); result.putarray("pixels", pixels); promise.resolve(result); } catch (exception e) { promise.reject(e); } } }
as can see in second file there method getpixels
, available js part of bitmap
native module. accepts path image file, converts image internal bitmap type, allows read image pixels. image pixels read 1 one , saved array of pixels in form of hex strings (because react native not allow pass hex values through bridge). these hex strings have 8 characters, 2 characters per argb channel: first 2 characters hex value alpha channel, second 2 - red, third 2 - green , last 2 - blue channel. example, value ffffffff
- white color , ff0000ff
- blue color. convenience, image width, height , presence of alpha channel returned along array of pixels. method returns promise object:
{ width: 1200, height: 800, hasalpha: false, pixels: ['ffffffff', 'ff00ffff', 'ffff00ff', ...] }
native module has registered in app, modify android/app/src/main/java/com/sampleapp/mainapplication.java
, add new module in there:
@override protected list<reactpackage> getpackages() { return arrays.<reactpackage>aslist( new mainreactpackage(), new bitmapreactpackage() // <--- ); }
how use js:
import { nativemodules } 'react-native'; const imagepath = '/storage/emulated/0/pictures/blob.png'; nativemodules.bitmap.getpixels(imagepath) .then((image) => { console.log(image.width); console.log(image.height); console.log(image.hasalpha); (let x = 0; x < image.width; x++) { (let y = 0; y < image.height; y++) { const offset = image.width * y + x; const pixel = image.pixels[offset]; } } }) .catch((err) => { console.error(err); });
i need mention, performs pretty slow, because of transfering huge array through bridge.
Comments
Post a Comment