mercredi 1 avril 2015

Picture convertion colours onPreviewFrame with NV21 to JPEG

For nearly 15 days I 'm stuck on the recording of frames in the event onPreviewFrame Android camera . My goal is very simple, I want to record five consecutive images at the click of a button. Only I do not want to block the preview of the camera , so I use the previewFrame . But during the recording of my image in jpeg on the sd card it is green and pink with many horizontal bars. A term I will send a list of byte [] on a Web API.


I already do a lot of research , trying to change the PictureSize and PreviewSize but nothing changes .


Another option would it not go through recording a video and extract the frame of it ?


Here is the code in my fragment :





package rocketweb.com.videocatcher.fragment;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import rocketweb.com.videocatcher.R;
import rocketweb.com.videocatcher.utilities.ImageHelper;

import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;

/**
* Created by Bastien on 15/03/2015.
*/
public class CameraFragment extends BaseFragment {

private Camera mCamera;
private CameraPreview mPreview;
private View mCameraView;
private List<byte[]> imagesFrame;
private boolean activeFrameCapture = false;

public CameraFragment(){
super();
}

public static CameraFragment newInstance(int sectionNumber) {
CameraFragment fragment = new CameraFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_video_catcher, container, false);
boolean opened = safeCameraOpenInView(view);

if(opened == false){
Log.d("Camera", "Error, Camera failed to open");
return view;
}

Button captureButton = (Button) view.findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
activeFrameCapture = !activeFrameCapture;
}
}
);

imagesFrame = new ArrayList<byte[]>(){};
return view;
}

private boolean safeCameraOpenInView(View view) {
boolean qOpened = false;
releaseCameraAndPreview();
mCamera = getCameraInstance();
mCameraView = view;
qOpened = (mCamera != null);

if(qOpened == true){
mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera,view);
FrameLayout preview = (FrameLayout) view.findViewById(R.id.camera_preview);
preview.addView(mPreview);
mPreview.startCameraPreview();
}
return qOpened;
}

public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
e.printStackTrace();
}
return c; // returns null if camera is unavailable
}

@Override
public void onPause() {
super.onPause();
}

@Override
public void onDestroy() {
super.onDestroy();
releaseCameraAndPreview();
}

private void releaseCameraAndPreview() {

if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if(mPreview != null){
mPreview.destroyDrawingCache();
mPreview.mCamera = null;
}
}

class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

private SurfaceHolder mHolder;
private Camera mCamera;
private Context mContext;
private Camera.Size mPreviewSize;
private List<Camera.Size> mSupportedPreviewSizes;
private List<String> mSupportedFlashModes;
private List<Camera.Size> mSupportedSizePicture;
private View mCameraView;

public CameraPreview(Context context, Camera camera, View cameraView) {
super(context);

// Capture the context
mCameraView = cameraView;
mContext = context;
setCamera(camera);

// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setKeepScreenOn(true);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

mCamera.setPreviewCallback(new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
if (activeFrameCapture && imagesFrame.size() <= 5) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
YuvImage im = new YuvImage(data, ImageFormat.NV21, size.width,size.height, null);
Rect r = new Rect(0,0,size.width,size.height);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
im.compressToJpeg(r, parameters.getJpegQuality(), baos);

try{
FileOutputStream output = new FileOutputStream(String.format(
"/sdcard/%s_%d.jpg", "test", System.currentTimeMillis()));
output.write(baos.toByteArray());
output.flush();
output.close();
}catch(FileNotFoundException e)
{
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}

imagesFrame.add(data);
}
}
});

}

public void startCameraPreview()
{
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
}
catch(Exception e){
e.printStackTrace();
}
}

private void setCamera(Camera camera)
{
mCamera = camera;
mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes();
mSupportedSizePicture = mCamera.getParameters().getSupportedPictureSizes();

Camera.Parameters parameters = mCamera.getParameters();

// Set the camera to Auto Flash mode.
if (mSupportedFlashModes != null && mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO))
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);

mCamera.setParameters(parameters);
requestLayout();
}

public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
}

public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null){
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
}
}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.

if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}

// stop preview before making changes
try {
Camera.Parameters parameters = mCamera.getParameters();

// Set the auto-focus mode to "continuous"
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

// Preview size must exist.
if(mPreviewSize != null) {
// 0 = landscape
// 90 = portrait

int rotation = getActivity().getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 90; break;
case Surface.ROTATION_90: degrees = 0; break;
}

mCamera.setDisplayOrientation(degrees);
if(degrees == 0)
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
else
parameters.setPreviewSize(mPreviewSize.height, mPreviewSize.width);

}

mCamera.setParameters(parameters);
mCamera.startPreview();
} catch (Exception e){
e.printStackTrace();
}
}

/**
* Calculate the measurements of the layout
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// Source: http://ift.tt/1OYoTFJ
final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
setMeasuredDimension(width, height);

if (mSupportedPreviewSizes != null){
mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
}
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom)
{
// Source: http://ift.tt/1OYoTFJ
if (changed) {
final int width = right - left;
final int height = bottom - top;

int previewWidth = width;
int previewHeight = height;

if (mPreviewSize != null){
Display display = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

switch (display.getRotation())
{
case Surface.ROTATION_0:
previewWidth = mPreviewSize.height;
previewHeight = mPreviewSize.width;
mCamera.setDisplayOrientation(90);
break;
case Surface.ROTATION_90:
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
break;
case Surface.ROTATION_180:
previewWidth = mPreviewSize.height;
previewHeight = mPreviewSize.width;
break;
case Surface.ROTATION_270:
previewWidth = mPreviewSize.width;
previewHeight = mPreviewSize.height;
mCamera.setDisplayOrientation(180);
break;
}
}

final int scaledChildHeight = previewHeight * width / previewWidth;
mCameraView.layout(0, height - scaledChildHeight, width, height);
}
}

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height)
{
// Source: http://ift.tt/1OYoTFJ
Camera.Size optimalSize = null;

final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) height / width;

// Try to find a size match which suits the whole screen minus the menu on the left.
for (Camera.Size size : sizes){

if (size.height != width) continue;
double ratio = (double) size.width / size.height;
if (ratio <= targetRatio + ASPECT_TOLERANCE && ratio >= targetRatio - ASPECT_TOLERANCE){
optimalSize = size;
}
}

// If we cannot find the one that matches the aspect ratio, ignore the requirement.
if (optimalSize == null) {
// TODO : Backup in case we don't get a size.
}

return optimalSize;
}

}
}



The layout of my fragment :





<RelativeLayout xmlns:android="http://ift.tt/nIICcg"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<FrameLayout
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>


<RelativeLayout
android:id="@+id/innerRelativeLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true" >
<Button
android:id="@+id/button_capture"
android:text="Capture"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_margin="10dp"
android:layout_gravity="bottom"
/>
</RelativeLayout>
</RelativeLayout>



My project configuration :





apply plugin: 'com.android.application'

android {
compileSdkVersion 21
buildToolsVersion "21.1.2"

defaultConfig {
applicationId "rocketweb.com.videocatcher"
minSdkVersion 15
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}

packagingOptions {
exclude 'META-INF/DEPENDENCIES.txt'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/LICENSE.txt'
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
compile 'com.google.code.gson:gson:2.3.1'
compile "org.apache.httpcomponents:httpmime:4.2.3"
}



End an exemple of image result : DropBox link to pictures


I can upload android studio project if needed. Thank you in advance for your help


ASP.NET picture gallery

I wanted to ask for an advice regarding picture gallery... The users on the website I'm working on should be able to add pictures into the gallery which will be displayed on public part of the website... I was wondering if the pictures which the users add should go to DB or file system? I understand that adding all those pictures to the DB would overload it and the DB would loose on its performance, so I was wondering what is the best way to handle this in ASP.NET? Is it by uploading the pictures to the file system or? What are best solutions? :)


Thanks!


Is it possible to specify the path of a chosen image with a variable?

Is it possible to determine the path of a chosen image with a variable? like this:



private JLabel label = new JLabel();
int number = 1;
label.setIcon(new ImageIcon(getClass().getResource("/image" + number + ".png")));


In this case it does not work, but my idea might be clear. In this case I could just simply change the variable name in order to change the path of my image. Does anybody know how to do so?


Drawing a boundary around some dots in an image

I have recently started working on opencv. I have an image having several dots in a line. I want to make a rectangular border around these dots. I have applied some basic C algorithm but it didn't work for me. This is my code.



int main()

{

cv::Mat image = imread("C:/Users/Ravi Sharma/Desktop/img.bmp");

for(int i =0; i < image.rows; i++){
for(int k = 0; k <image.cols; k ++){
if((image.at<cv::Vec3b>(k,i)[0] == 0)&&(image.at<cv::Vec3b>(k,i)[1] == 135)&&(image.at<cv::Vec3b>(k,i)[2] == 255))
{
(image.at<cv::Vec3b>(k,i)[0] = 0)&&(image.at<cv::Vec3b>(k,i)[1] = 0)&&(image.at<cv::Vec3b>(k,i)[2] = 255);
}
}

}
imwrite("C:/Users/Ravi Sharma/Desktop/img1.bmp",image);
cv::namedWindow("Window1");
cv::imshow("Window1",image);
cv::waitKey(50000);
return 1;
}


This code is not updating the pixel value. Please help me correcting the code to get the desired result. How I can use cvminmaxloc function to do the same. Thanx in advance.


Get average outer pixel color of image

So I want to get the average color of the outer pixels in an image, to give the background of the div the image is shown in, the same color. So I won't have to make all images the background color myself.


Example: if the image is 100px x 100px, you check the 5 outer pixels at the top of the image, 5 outer pixels of the right side of the image, same for left and bottom. You will get 5 x 100 x 4 pixels, get the colors, check the average and let JS give the div the same background.


So if the average color is #000000, the div BG will be #000000. If average is #FAFAFA, the div BG will be #FAFAFA


Configurate Linux Iso-Image as bootable Thin-Client DVD

Hello Everyone :-)


I have to find a solution for the special needs of my company and now i getting struggle, i have the following problem.


The order: Create a bootable Linux DVD with special RDP settings.


We have many (not so) old computers and we want to recycle them as Thin-Client, but without any HD, therefore the Linux-DVD. The DVD should boot and after starting the Desktop the RDP-Connection should connection.


What i have done: - Write the RDP-Scripts to start with the desktop. - "Play" with mounting, sqaushfs and tools like remastersys


Where i struggle: Tools like remastersys don't suit me needs, i need special seetings (as explained). I try to customize a Ubuntu-Iso in this way that it start a desktop and then an RDP-Session. I used squashfs to extract the ISO but how do is customize it to use it as it need? Where i have to place the files and wrap it back to iso?


Thx for the help :-)


PS: plz don't consider my orthography :-)


GridView adapter with Viewholder to load images

I want to download Images and place them in a grid, But the images don't show up and every +- 1 second, a new thread gets started ?! Also getview is called multiple times with position 0, which i also don't understand.


I'm using Xamarin



public override View GetView(int position, View convertView, ViewGroup parent)
{
View view= convertView;
ViewHolder holder;

if (view == null)
{ // if it's not recycled, initialize some attributes
holder = new ViewHolder();
view = mContext.LayoutInflater.Inflate (Resource.Layout.teamMemberLayout, null);
holder.Image = view.FindViewById<ImageView>(Resource.Id.teamIv);
holder.Name = view.FindViewById<TextView>(Resource.Id.nameTv);
holder.Name.SetTypeface (MainModel.Instance.RegularFont,TypefaceStyle.Normal);
view.Tag = holder;
}
else //recycled view:
{
holder = (ViewHolder)view.Tag;
}

holder.Name.Text=_teamMembers[position].fName;
holder.SetImage (_teamMembers[position],(int)ConvertDpToPix(72),(int)ConvertDpToPix(72));

return view;
}

public float ConvertDpToPix(float dp)
{
return dp * mContext.Resources.DisplayMetrics.Density;
}
}

class ViewHolder : Java.Lang.Object
{
public ImageView Image { get; set; }
public TextView Name { get; set; }

public async void SetImage(UserVO user, int width,int height)
{
Bitmap profileImg = await MainModel.Instance.getProfileImage (user.Profilepicture,width,height);
Image.SetImageBitmap (profileImg);

}

}