Im trying to get my bitmap to fit in my imageview by using the tutorial on android devs but i dont know what to throw in this line imageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
this is my full onActivityResult
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE_CONTENT_RESOLVER) {
if (resultCode == RESULT_OK) {
// Image saved to a generated MediaStore.Images.Media.EXTERNAL_CONTENT_URI
String[] projection = {
MediaStore.MediaColumns._ID,
MediaStore.Images.ImageColumns.ORIENTATION,
MediaStore.Images.Media.DATA
};
Cursor c = getContentResolver().query(mPhotoUri, projection, null, null, null);
c.moveToFirst();
String photoFileName = c.getString(c.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(photoFileName);
imageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
these are the methods on the android devs
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
}
Im sorry if this is a not a good question but im trying to learn android developing at the moment.
fix it by making the two methods into a class.
Related
I am clicking the picture and the passing it through intent. But the image that I am displaying on the ImageView is the mirror image of the image captured. I have tried to implement RotateFlip method but the error appears saying Bitmap doesn't contain definition of RotateFlip.
{
var metrics = Resources.DisplayMetrics;
int windowWidth = metrics.WidthPixels;
int windowHeight = metrics.HeightPixels;
int reqWidth = (int)Math.Round(windowWidth*1.0f);
int reqHeight = (int)Math.Round(windowHeight*1.0f);
Bitmap photo = loadBitmapLowResolution(Image, reqWidth, reqHeight);
ExifInterface exif = new ExifInterface(Image);
int orientation = exif.GetAttributeInt(ExifInterface.TagOrientation, 90);
var rotation = exif.GetAttributeInt(ExifInterface.TagOrientation, (int)Orientation.Normal);
orientation = exif.GetAttributeInt(ExifInterface.TagOrientation, (int)Orientation.Rotate90);
// Rotate according to the orientation
Matrix matrix = new Matrix();
switch (orientation)
{
case (int)Orientation.Rotate90: matrix.PostRotate(90); break;
case (int)Orientation.Rotate180: matrix.PostRotate(180); break;
case (int)Orientation.Rotate270: matrix.PostRotate(270); break;
}
Bitmap photoRotated;
if (orientation != (int)Orientation.Normal)
{
photoRotated = Bitmap.CreateBitmap(photo, 0, 0, photo.Width, photo.Height, matrix, true);
}
else
{
photoRotated = photo;
}
// Apply center crop
int cropW = (int)(0.5 * (photoRotated.Width - photoRotated.Width/1.0f ) - 2);
int cropH = (int)(0.5 * (photoRotated.Height - photoRotated.Height/1.0f ) - 2);
cropW = cropW < 0 ? 0 : cropW;
cropH = cropH < 0 ? 0 : cropH;
//Log.Debug(TAG, "Creating a bitmap with size: " + (photoRotated.Width - 2 * cropW) + "x" + (photoRotated.Height - 2 * cropH) + " from a bitmap with size: " + photoRotated.Width + "x" + photoRotated.Height);
Bitmap photoCrop = Bitmap.CreateBitmap(photoRotated, cropW, cropH, photoRotated.Width - 2 * cropW, photoRotated.Height- 2 * cropH);
imageView.SetImageBitmap(photoCrop);
// Create your application here,
}
public static Bitmap loadBitmapLowResolution(string filePath, int reqWidth, int reqHeight)
{
BitmapFactory.Options options = new BitmapFactory.Options();
// First decode with inJustDecodeBounds=true to check dimensions
options.InJustDecodeBounds = true;
BitmapFactory.DecodeFile(filePath, options);
// Calculate inSampleSize
options.InSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.InJustDecodeBounds = false;
return BitmapFactory.DecodeFile(filePath, options);
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
int height = options.OutHeight;
int width = options.OutWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth)
{
// Calculate ratios of height and width to requested height and width
int heightRatio = (int)Math.Round((float)height / (float)reqHeight);
int widthRatio = (int)Math.Round((float)width / (float)reqWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
The easiest way is to do it is using a Matrix;
public Bitmap HorizontalFlip(Bitmap bInput)
{
if (bInput == null) return null;
Matrix matrix = new Matrix();
matrix.PreScale(-1.0f, 1.0f);
return Bitmap.CreateBitmap(bInput, 0, 0, bInput.Width, bInput.Height, matrix, true);
}
Where bInput is the input bitmap that you wanna flip.
I'm trying to save an image after certain time, the problem is that the image size is bigger than the display so when I use the save or saveFrame function it only saves the image that I can see in the display. There is any other way to save the whole image?
This is my code:
PImage picture, pictureFilter, img;
int total, cont, current;
ArrayList<ArrayList<Position>> columns;
String[] fontList;
public class Position {
public int x;
public int y;
}
void setup() {
fontList = PFont.list();
picture = loadImage("DSC05920b.JPG");
pictureFilter = loadImage("filtrePort2.jpg");
frame.setResizable(true);
size(picture.width, picture.height);
columns = new ArrayList<ArrayList<Position>>();
for(int i = 0; i < picture.width; i++) {
ArrayList<Position> row = new ArrayList<Position>();
for(int j = 0; j < picture.height; j++){
Position p = new Position();
p.x = i;
p.y = j;
row.add(p);
}
columns.add(row);
}
total = picture.width * picture.height;
cont = total;
current = 0;
img = createImage(picture.width, picture.height, RGB);
}
float randomLetter() {
float value = 23;
boolean found = false;
while(!found) {
value = random(48, 122);
if(value >48 && value <58) found = true;
if(value >65 && value <91) found = true;
if(value >97 && value <123) found = true;
}
return value;
}
void draw() {
int x = int(random(0, columns.size()));
ArrayList<Position> rows = columns.get(x);
int y = int(random(0, rows.size()));
Position p = rows.get(y);
color c = pictureFilter.get(p.x, p.y);
int r = (c >> 16) & 0xFF; // Faster way of getting red(argb)
if(r < 240) {
PFont f = createFont(fontList[int(random(0,fontList.length))],random(5, 24),true);
textFont(f);
fill(picture.get(p.x,p.y));
char letter = (char) int(randomLetter());
text(letter, p.x, p.y);
}
if(rows.size() == 1) {
if(columns.size() == 1) {
saveFrame("lol.jpg");
columns.remove(x);
} else {
columns.remove(x);
}
} else {
println(rows.size());
rows.remove(y);
}
--cont;
float percent = float(total-cont)/float(total)*100;
if(int(percent) != current) {
current = int(percent);
save("image_" + current + ".jpg");
}
println("DONE: " + (total-cont) + "/" + total + " Progress: " + percent + "%");
}
The code do a lot of stuff but the part that its not working well is at the final when I check if the percentage have been increased in order to save the image
You can write this into a PGraphics context - aka a graphics buffer.
The buffer can be as big as you need it to be, and you can choose whether to draw it on the screen or not..
// Create the buffer at the size you need, and choose the renderer
PGraphics pg = createGraphics(myImage.width, myImage.height, P2D);
// Wrap all your drawing functions in the pg context - e.g.
PFont f = createFont(fontList[int(random(0,fontList.length))],random(5, 24),true);
textFont(f);
pg.beginDraw();
pg.fill(picture.get(p.x,p.y));
char letter = (char) int(randomLetter());
pg.text(letter, p.x, p.y);
pg.endDraw();
// Draw your PG to the screen and resize the representation of it to the screen bounds
image(pg, 0, 0, width, height); // <-- this wont actually clip/resize the image
// Save it
pg.save("image_" + current + ".jpg");
The PImage class contains a save() function that exports to file. The API should be your first stop for questions like this.
The code works, but the images get trimmed off from the top. I have tried everything, but I still can't figure it out.
Can someone please take a look at it?
Thanks in advance.
Code:
public class ScalingUtilities {
public static Bitmap decodeResource(Resources res, int resId, int ReqWidth, int ReqHeight, ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, ReqWidth,
ReqHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeResource(res, resId, options);
return unscaledBitmap;
}
public static Bitmap decode_imagePath_String(String image_path, int ReqWidth, int ReqHeight, ScalingLogic scalingLogic) {
Options options = new Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(image_path, options);
options.inJustDecodeBounds = false;
options.inSampleSize = calculateSampleSize(options.outWidth, options.outHeight, ReqWidth,
ReqHeight, scalingLogic);
Bitmap unscaledBitmap = BitmapFactory.decodeFile(image_path, options);
return unscaledBitmap;
}
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int ReqWidth, int ReqHeight,
ScalingLogic scalingLogic) {
Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
ReqWidth, ReqHeight, scalingLogic);
Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
ReqWidth, ReqHeight, scalingLogic);
Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
Config.RGB_565);
Canvas canvas = new Canvas(scaledBitmap);
canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));
return scaledBitmap;
}
public static enum ScalingLogic {
CROP, FIT
}
public static int calculateSampleSize(int srcWidth, int srcHeight, int ReqWidth, int ReqHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)ReqWidth / (float)ReqHeight;
if (srcAspect > dstAspect) {
return srcWidth / ReqWidth;
} else {
return srcHeight / ReqHeight;
}
} else {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)ReqWidth / (float)ReqHeight;
if (srcAspect > dstAspect) {
return srcHeight / ReqHeight;
} else {
return srcWidth / ReqWidth;
}
}
}
public static Rect calculateSrcRect(int srcWidth, int srcHeight, int ReqWidth, int ReqHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.CROP) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)ReqWidth / (float)ReqHeight;
if (srcAspect > dstAspect) {
final int srcRectWidth = (int)(srcHeight * dstAspect);
final int srcRectLeft = (srcWidth - srcRectWidth) / 2;
return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
} else {
final int srcRectHeight = (int)(srcWidth / dstAspect);
final int scrRectTop = (int)(srcHeight - srcRectHeight) / 2;
return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
}
} else {
return new Rect(0, 0, srcWidth, srcHeight);
}
}
public static Rect calculateDstRect(int srcWidth, int srcHeight, int ReqWidth, int ReqHeight,
ScalingLogic scalingLogic) {
if (scalingLogic == ScalingLogic.FIT) {
final float srcAspect = (float)srcWidth / (float)srcHeight;
final float dstAspect = (float)ReqWidth / (float)ReqHeight;
if (srcAspect > dstAspect) {
return new Rect(0, 0, ReqWidth, (int)(ReqWidth / srcAspect));
} else {
return new Rect(0, 0, (int)(ReqHeight * srcAspect), ReqHeight);
}
} else {
return new Rect(0, 0, ReqWidth, ReqHeight);
}
}
}
I very appreciate it...
In calculateSampleSize, you are returning int. Depending on the ratio of your image, this return value may very well be 0 and options.inSampleSize will be 0, so no scaling will take place.
Then the decode will decode with the size values you passed, so cropping will occur. I think that you need to use the density parameters instead. Please take a look at this post
I'm having a ton of trouble making a simple video delay in processing. I looked around on the internet and I keep finding the same bit of code and I can't get it to work at all. When I first tried it, it did nothing (at all). Here's my modified version (which at least seems to load frames into the buffer), I really have no idea why it doesn't work and I'm getting really tired of pulling out my hair. Please... please, for the love of god, please somebody point out the stupid mistake I'm making here.
And now, without further delay (hah, get it?), the code:
import processing.video.*;
VideoBuffer vb;
Movie myMovie;
Capture cam;
float seconds = 1;
void setup() {
size(320,240, P3D);
frameRate(30);
String[] cameras = Capture.list();
if (cameras.length == 0) {
println("There are no cameras available for capture.");
exit();
} else {
println("Available cameras:");
for (int i = 0; i < cameras.length; i++) {
println(cameras[i]);
}
cam = new Capture(this, cameras[3]);
cam.start();
}
vb = new VideoBuffer(90, width, height);
}
void draw() {
if (cam.available() == true) {
cam.read();
vb.addFrame(cam);
}
image(cam, 0, 0);
image( vb.getFrame(), 150, 0 );
}
class VideoBuffer
{
PImage[] buffer;
int inputFrame = 0;
int outputFrame = 0;
int frameWidth = 0;
int frameHeight = 0;
VideoBuffer( int frames, int vWidth, int vHeight )
{
buffer = new PImage[frames];
for(int i = 0; i < frames; i++)
{
this.buffer[i] = new PImage(vWidth, vHeight);
}
this.inputFrame = 0;
this.outputFrame = 1;
this.frameWidth = vWidth;
this.frameHeight = vHeight;
}
// return the current "playback" frame.
PImage getFrame()
{
return this.buffer[this.outputFrame];
}
// Add a new frame to the buffer.
void addFrame( PImage frame )
{
// copy the new frame into the buffer.
this.buffer[this.inputFrame] = frame;
// advance the input and output indexes
this.inputFrame++;
this.outputFrame++;
println(this.inputFrame + " " + this.outputFrame);
// wrap the values..
if(this.inputFrame >= this.buffer.length)
{
this.inputFrame = 0;
}
if(this.outputFrame >= this.buffer.length)
{
this.outputFrame = 0;
}
}
}
This works in Processing 2.0.1.
import processing.video.*;
Capture cam;
PImage[] buffer;
int w = 640;
int h = 360;
int nFrames = 60;
int iWrite = 0, iRead = 1;
void setup(){
size(w, h);
cam = new Capture(this, w, h);
cam.start();
buffer = new PImage[nFrames];
}
void draw() {
if(cam.available()) {
cam.read();
buffer[iWrite] = cam.get();
if(buffer[iRead] != null){
image(buffer[iRead], 0, 0);
}
iWrite++;
iRead++;
if(iRead >= nFrames-1){
iRead = 0;
}
if(iWrite >= nFrames-1){
iWrite = 0;
}
}
}
There is a problem inside your addFrame-Method. You just store a reference to the PImage object, whose pixels get overwritten all the time. You have to use buffer[inputFrame] = frame.get() instead of buffer[inputFrame] = frame. The get() method returns a copy of the image.
It's easy to show some animation within one field - BitmapField or Screen:
[Blackberry - background image/animation RIM OS 4.5.0][1]
But what if you need to move fields, not just images?
May be used:
game workflow functionality, like chess, puzzle etc
application user-defined layout, like in Google gadgets
enhanced GUI animation effects
So, I'd like to exchange my expirience in this task, on the other hand, I'd like to know about any others possibilities and suggestions.
This effect may be easily achived with custom layout:
class AnimatedManager extends Manager {
int ANIMATION_NONE = 0;
int ANIMATION_CROSS_FLY = 1;
boolean mAnimationStart = false;
Bitmap mBmpBNormal = Bitmap.getBitmapResource("blue_normal.png");
Bitmap mBmpBFocused = Bitmap.getBitmapResource("blue_focused.png");
Bitmap mBmpRNormal = Bitmap.getBitmapResource("red_normal.png");
Bitmap mBmpRFocused = Bitmap.getBitmapResource("red_focused.png");
Bitmap mBmpYNormal = Bitmap.getBitmapResource("yellow_normal.png");
Bitmap mBmpYFocused = Bitmap.getBitmapResource("yellow_focused.png");
Bitmap mBmpGNormal = Bitmap.getBitmapResource("green_normal.png");
Bitmap mBmpGFocused = Bitmap.getBitmapResource("green_focused.png");
int[] width = null;
int[] height = null;
int[] xPos = null;
int[] yPos = null;
BitmapButtonField mBButton = new BitmapButtonField(mBmpBNormal,
mBmpBFocused);
BitmapButtonField mRButton = new BitmapButtonField(mBmpRNormal,
mBmpRFocused);
BitmapButtonField mYButton = new BitmapButtonField(mBmpYNormal,
mBmpYFocused);
BitmapButtonField mGButton = new BitmapButtonField(mBmpGNormal,
mBmpGFocused);
public AnimatedManager() {
super(USE_ALL_HEIGHT | USE_ALL_WIDTH);
add(mBButton);
add(mRButton);
add(mYButton);
add(mGButton);
width = new int[] { mBButton.getPreferredWidth(),
mRButton.getPreferredWidth(),
mYButton.getPreferredWidth(),
mGButton.getPreferredWidth() };
height = new int[] { mBButton.getPreferredHeight(),
mRButton.getPreferredHeight(),
mYButton.getPreferredHeight(),
mGButton.getPreferredHeight() };
xPos = new int[] { 0, getPreferredWidth() - width[1], 0,
getPreferredWidth() - width[3] };
yPos = new int[] { 0, 0, getPreferredHeight() - height[2],
getPreferredHeight() - height[3] };
Timer timer = new Timer();
timer.schedule(mAnimationTask, 0, 100);
}
TimerTask mAnimationTask = new TimerTask() {
public void run() {
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
updateLayout();
};
});
};
};
MenuItem mAnimationMenuItem = new MenuItem("Start", 0, 0) {
public void run() {
mAnimationStart = true;
};
};
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
menu.add(mAnimationMenuItem);
}
public int getPreferredHeight() {
return Display.getHeight();
}
public int getPreferredWidth() {
return Display.getWidth();
}
protected void sublayout(int width, int height) {
width = getPreferredWidth();
height = getPreferredHeight();
if (getFieldCount() > 3) {
Field first = getField(0);
Field second = getField(1);
Field third = getField(2);
Field fourth = getField(3);
layoutChild(first, this.width[0], this.height[0]);
layoutChild(second, this.width[1], this.height[1]);
layoutChild(third, this.width[2], this.height[2]);
layoutChild(fourth, this.width[3], this.height[3]);
if (mAnimationStart) {
boolean anim1 = performLayoutAnimation(0,
width - this.width[0],
height - this.height[0]);
boolean anim2 = performLayoutAnimation(1, 0,
height - this.height[1]);
boolean anim3 = performLayoutAnimation(2,
width - this.width[2], 0);
boolean anim4 = performLayoutAnimation(3, 0, 0);
mAnimationStart = anim1 || anim2 || anim3 || anim4;
}
setPositionChild(first, xPos[0], yPos[0]);
setPositionChild(second, xPos[1], yPos[1]);
setPositionChild(third, xPos[2], yPos[2]);
setPositionChild(fourth, xPos[3], yPos[3]);
}
setExtent(width, height);
}
boolean performLayoutAnimation(int fieldIndex, int x, int y) {
boolean result = false;
if (xPos[fieldIndex] > x) {
xPos[fieldIndex] -= 2;
result = true;
} else if (xPos[fieldIndex] < x) {
xPos[fieldIndex] += 2;
result = true;
}
if (yPos[fieldIndex] > y) {
yPos[fieldIndex] -= 1;
result = true;
} else if (yPos[fieldIndex] < y) {
yPos[fieldIndex] += 1;
result = true;
}
return result;
}
}
BitmapButtonField class I've used:
class BitmapButtonField extends ButtonField {
Bitmap mNormal;
Bitmap mFocused;
int mWidth;
int mHeight;
public BitmapButtonField(Bitmap normal, Bitmap focused) {
super(CONSUME_CLICK);
mNormal = normal;
mFocused = focused;
mWidth = mNormal.getWidth();
mHeight = mNormal.getHeight();
setMargin(0, 0, 0, 0);
setPadding(0, 0, 0, 0);
setBorder(BorderFactory.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
setBorder(VISUAL_STATE_ACTIVE, BorderFactory
.createSimpleBorder(new XYEdges(0, 0, 0, 0)));
}
protected void paint(Graphics graphics) {
Bitmap bitmap = null;
switch (getVisualState()) {
case VISUAL_STATE_NORMAL:
bitmap = mNormal;
break;
case VISUAL_STATE_FOCUS:
bitmap = mFocused;
break;
case VISUAL_STATE_ACTIVE:
bitmap = mFocused;
break;
default:
bitmap = mNormal;
}
graphics.drawBitmap(0, 0, bitmap.getWidth(), bitmap.getHeight(),
bitmap, 0, 0);
}
public int getPreferredWidth() {
return mWidth;
}
public int getPreferredHeight() {
return mHeight;
}
protected void layout(int width, int height) {
setExtent(mWidth, mHeight);
}
protected void applyTheme(Graphics arg0, boolean arg1) {
}
}