Showing a fix boundary box to capture image - ionic-framework

My ionic appp is to take pictures of business cards. as 99% of the business cards are landscape style so users tries to change the camera orientation to landscape mode as well. This is a natural behavior.
However, i want to avoid that and one way is to show a rectangle while camera is open (width equal to screen width and a 3:2 aspect ratio for height)
This will make life easy as users wont try to change the camera orientation.
I was looking into camera plugin which uses code like
this.camera.getPicture({
destinationType: this.camera.DestinationType.DATA_URL,
quality: 25,
correctOrientation: true,
allowEdit:false,
sourceType: this.camera.PictureSourceType.SAVEDPHOTOALBUM
}).then(async(imageData) => {
//console.log("image data is:" + imageData)
// imageData is a base64 encoded string
var base64Image = "data:image/jpeg;base64," + imageData;
I was trying targetWidth and height but that does not draw that box like i have seen in many other apps.
there are other plugins like cropperJs but seems they let u crop the image after taken which not what i need.

Use camera-preview-plugin instead of camera for that :
const cameraPreviewOpts: CameraPreviewOptions = {
x: 0,
y: 0,
width: window.screen.width,
height: window.screen.height,
camera: 'rear',
tapPhoto: true,
previewDrag: true,
toBack: true,
alpha: 1
}
Ionic Camera Preview

Related

How do I set the resolution in Flutter's Camera package

I'm working on a flutter app that is using the Camera package's camera preview.
I'm initializing the camera controller like so:
final controller = CameraController(
_cameras[0],
ResolutionPreset.ultraHigh,
enableAudio: false,
imageFormatGroup: ImageFormatGroup.bgra8888,
);
The ResolutionPreset enum has these options:
enum ResolutionPreset {
/// 352x288 on iOS, 240p (320x240) on Android
low,
/// 480p (640x480 on iOS, 720x480 on Android)
medium,
/// 720p (1280x720)
high,
/// 1080p (1920x1080)
veryHigh,
/// 2160p (3840x2160)
ultraHigh,
/// The highest resolution available.
max,
}
The resolution needs to be 4032x2034. How do I use a custom resolution?
ResolutionPreset enum doesn't provide the option to set a custom resolution. As a workaround, you can use ResolutionPreset.max then resize the image. Using the image package, you can resize the image to the desired width and height and write it on storage.
// Read a jpeg image from file path
Image image = decodeImage(File('image path').readAsBytesSync());
// Resize the image
Image resizedImage = copyResize(image, width: 4032, height: 2034);
// Save the image as jpg
File('out/image-resized.jpg')
..writeAsBytesSync(encodeJpg(resizedImage, quality: 100));

What is the correct way to parent ImageBundles in the Bevy game engine so the child image doesn't alter the size of the parent image?

When I try to parent two ImageBundles together I don't get the expected result. The child image causes the parent image to resize to the size of the child image. I am trying to place the button image on top of the background image, but the following code places the button image on the background image and then scales the background image to the size of the button image.
If I comment out the push_children line of code then both images are displayed at the correct size.
let ent1 = commands.spawn_bundle(ImageBundle {
style: Style {
align_self: AlignSelf::Center,
..Default::default()
},
material: materials.add(
asset_server.load("Background.png").into()),
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)),
..Default::default()
}).id();
let ent2 = commands.spawn_bundle(ImageBundle {
style: Style {
align_self: AlignSelf::Center,
..Default::default()
},
material: materials.add(
asset_server.load("button.png").into()),
transform: Transform::from_translation(Vec3::new(0.0, 0.0, 0.0)),
..Default::default()
}).id();
commands.entity(ent1).push_children(&[ent2]);

How to resize an image in flutter with conditional statements

I achieved to resize my images using the package image
What I want to achieve is a conditional statement that reduces the size of the image if image is > than max (1920) and dont resize it otherwise.
This is my code:
Widget build(BuildContext context) {
void uploadImage(File result) async {
var image = decodeImage(result.readAsBytesSync());
var thumbnail = copyResize(image, width: 1920);
var encoded = base64.encode(encodeJpg(thumbnail));
var userAccount =
await context.api.customersApi.accounts.uploadProfileImage(defaultOrganisationId, context.blocs.auth.state.user.id, ImageUploadRequest(encoded));
// update the current user
context.blocs.auth.updateUserAccount(userAccount.data);
}
You can check the width and height of the image:
if (image.width > 1920 || image.height > 1920) {
thumbnail = copyResze(image, width: 1920, height: 1920);
}
else {
thumbnail = image;
}
I'm assuming you care mostly about the file size (~ area) of the image, though you should have no problem changing it to look at only one coordinate.
I might also note that a 1920 pixels wide image no longer qualifies as a thumbnail in my opinion, that's as wide as my entire screen.
From the Docs,
I think you can use both height and width property.
Here it like, image.height and image.width.
Hope that works!

Having issues with drawing to a frame buffer texture. It draws blank

I am in OpenGL es 2.0 with glKit trying to render to iOS devices.
Basically my goal is to instead of drawing to the main buffer draw to a texture. Then render that texture to the screen. I have been trying to follow another topic on so. Unfortunately they mention something about the power of two (im assuming with regards to resolution) but I don't know how to fix it. Anyway here is my swift interpretation of the code from that topic.
import Foundation
import GLKit
import OpenGLES
class RenderTexture {
var framebuffer:GLuint = 0
var tex:GLuint = 0
var old_fbo:GLint = 0
init(width: GLsizei, height: GLsizei)
{
glGetIntegerv(GLenum(GL_FRAMEBUFFER_BINDING), &old_fbo)
glGenFramebuffers(1, &framebuffer)
glGenTextures(1, &tex)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), framebuffer)
glBindTexture(GLenum(GL_TEXTURE_2D), tex)
glTexImage2D(GLenum(GL_TEXTURE_2D), 0, GL_RGBA, GLsizei(width), GLsizei(height), 0, GLenum(GL_RGBA), GLenum(GL_UNSIGNED_BYTE), nil)
glFramebufferTexture2D(GLenum(GL_FRAMEBUFFER), GLenum(GL_COLOR_ATTACHMENT0), GLenum(GL_TEXTURE_2D), tex, 0)
glClearColor(0, 0.1, 0, 1)
glClear(GLenum(GL_COLOR_BUFFER_BIT))
let status = glCheckFramebufferStatus(GLenum(GL_FRAMEBUFFER))
if (status != GLenum(GL_FRAMEBUFFER_COMPLETE))
{
print("DIDNT GO WELL WITH", width, " " , height)
print(status)
}
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), GLenum(old_fbo))
}
func begin()
{
glGetIntegerv(GLenum(GL_FRAMEBUFFER_BINDING), &old_fbo)
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), framebuffer)
}
func end()
{
glBindFramebuffer(GLenum(GL_FRAMEBUFFER), GLenum(old_fbo))
}
}
Then as far as rendering I have some things going on.
A code that theoretically renders any texture full screen. This has been tested with two manually loaded pngs (using no buffer changes) and works great.
func drawTriangle(texture: GLuint)
{
loadBuffers()
//glViewport(0, 0, width, height)
//glClearColor(0, 0.0, 0, 1.0)
//glClear(GLbitfield(GL_COLOR_BUFFER_BIT) | GLbitfield(GL_DEPTH_BUFFER_BIT))
glEnable(GLenum(GL_TEXTURE_2D))
glActiveTexture(GLenum(GL_TEXTURE0))
glUseProgram(texShader)
let loc1 = glGetUniformLocation(texShader, "s_texture")
glUniform1i(loc1, 0)
let loc3 = glGetUniformLocation(texShader, "matrix")
if (loc3 != -1)
{
glUniformMatrix4fv(loc3, 1, GLboolean(GL_FALSE), &matrix)
}
glBindTexture(GLenum(GL_TEXTURE_2D), texture)
glDrawArrays(GLenum(GL_TRIANGLE_STRIP), 0, 6)
glDisable(GLenum(GL_TEXTURE_2D))
destroyBuffers()
}
I also have a function that draws a couple dots on the screen. You dont really need to see the methods but it works. This is how I am going to know that OpenGL is drawing from the buffer texture and NOT a preloaded texture.
Finally here is the gist of the code I am trying to do.
func initialize()
{
nfbo = RenderTexture(width: width, height: height)
}
fun draw()
{
glViewport(0, 0, GLsizei(width * 2), GLsizei(height * 2)) //why do I have to multiply for 2 to get it to work?????
nfbo.begin()
drawDots() //Draws the dots
nfbo.end()
reset()
drawTriangle(nfbo.tex)
}
At the end of all this all that is drawn is a blank screen. If there is any more code that would help you figure things out let me know. I tried to trim it to make it less annoying for you.
Note: Considering the whole power of two thing I have tried passing the fbo class 512 x 512 just in case it would make things work being a power of two. Unfortunately it didnt do that.
Another Note: All I am doing is going to be 2D so I dont need depth buffers right?
yesterday I saw exactly the same issue.
after struggling for hours, I found out why.
the trick is configuring your texture map with the following:
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), GL_CLAMP_TO_EDGE);
glTexParameteri(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), GL_CLAMP_TO_EDGE);
otherwise, you won't draw anything on the texture map.
the reason seems to be that while ios supports texture maps that are not power of 2. it requires GL_CLAMP_TO_EDGE. otherwise it won't work.
it should really report incomplete framebuffer. it took me quite long time to debug this problem!
here a related discussion:
Rendering to non-power-of-two texture on iPhone

Cropping image with CIImage.ImageByCroppingToRect or CICrop in MonoTouch

I have a very large image that I would like to show a 200x200px thumbnail of (showing a portion of the image, not a strethed version of the entire image). To achieve this I am looking into using CIImage.ImageByCroppingToRect or CICrop - but I am not able to get anything useful. Either the result is just black (I assume what I see is the black portion of the cropped image) or I get a SIGABRT ("Cannot handle a (6000 x 3000) sized texture with the given GLES context!")
There is a ObjC sample in this thread:
Cropping CIImage with CICrop isn't working properly
But I haven't managed to translate it in to C# and get it working properly.
Here's a MonoTouch port of the answer from the post you mentioned:
var croppedImaged = CIImage.FromCGImage (inputCGImage).ImageByCroppingToRect (new RectangleF (150, 150, 300, 300));
var transformFilter = new CIAffineTransform();
var affineTransform = CGAffineTransform.MakeTranslation (-150, 150);
transformFilter.Transform = affineTransform;
transformFilter.Image = croppedImaged;
CIImage transformedImage = transformFilter.OutputImage;