I want to rotate(-45 to 45 degrees like tilt feature) and scale the image based on the degree.
I tried to set the scale value by using this calculation (angle * Math.PI) / 180.0. But it is not scaling the image based on the image size. If I set the horizontal image means there is a space in left and right side of the image.
Can you please provide any suggestions on this?
I was able to rotate the image using following code. compasImageView is image which i was rotating 360 degree
private void Rotateimage(double angle)
{
ObjectAnimator objectAnimator = ObjectAnimator.OfFloat(compasImageView, "rotation", 130, 0f);
objectAnimator.SetDuration(500);
objectAnimator.Start();
compasImageView.Animate().RotationBy((float)angle).SetDuration(1500).SetInterpolator(new LinearInterpolator()).Start();
}
Can you please share your code. If suggested code is not helping.
Related
I have two play two videos simultaneously on a view .Both videos would be same.
Now, my concern is the video on right is actually to be flipped horizontally along x-axis and then saved in photo library.I have tried googling a lot and found that CGAFFineRotateTransform can help but I am not able to use that in my code.Kindly help me to flip the video on right horizontally while keeping the scale and move same.
Any help or guidance in this direction would be appreciable .Thanks in advance!
Check the difference between video on left and right,video on left is complete but video on right is showing half video only
To just flip (mirror) the video horizontally, use a negative x-value for scaling:
CGAffineTransform scale = CGAffineTransformMakeScale( -1.0, 1.0);
Edit: Regarding your more general question on how to position tracks: For each video track involved:
build a bounding rect based on the original size of the track - this is the source rect
ask yourself where the track should end up, in terms of origin and size in the resulting video - this gives you the destination rect
You can then derive the corresponding affine transform with a function like:
CGAffineTransform NHB_CGAffineTransformMakeRectToRect( CGRect srcRect, CGRect dstRect)
{
CGAffineTransform t = CGAffineTransformIdentity;
t = CGAffineTransformTranslate( t, dstRect.origin.x - fmin( 0., dstRect.size.width), dstRect.origin.y - fmin( 0., dstRect.size.height));
t = CGAffineTransformScale( t, dstRect.size.width / srcRect.size.width, dstRect.size.height / srcRect.size.height);
return t;
}
To mirror, provide a negative size for the corresponding axis (the - fmin(,) part compensates the offset).
Given a video track and assuming, for example, the track should go mirrored to the right half of a 640x480 video, you can get the corresponding transform with:
CGSize srcSize = videoTrack.naturalSize;
CGRect srcRect = CGRectMake( 0, 0, srcSize.width, srcSize.height);
CGRect dstRect = CGRectMake( 320, 0, -320, 480);
CGAffineTransform t = NHB_CGAffineTransformMakeRectToRect(srcRect, dstRect);
Of course this may stretch the video track; to keep the aspect ratio, you'll have to take the source size into account when calculating the destination rect.
Some remarks:
note that in NHB_CGAffineTransformMakeRectToRect I deliberately chose to start with the identity matrix, and then add the required transforms one by one. This way much more complex transforms can be build, including rotation. As I said, try to get a grasp on affine transforms, they're really powerful
AVAssetTracks naturalSize sometimes returns confusing results for some videos with complex SAR/PAR definitions. To make this bullet proof, you'll have to derive the size from the dimensions in the corresponding format descriptions, but that's a whole new topic...
I am using image magick for .net to cropping and resizing the images. But the problem with the library is that it only crop the bottom of the image. Isn't there any way by means which we can crop it evenly from both up and down or left and right?
Edited question :
MagickGeometry size = new MagickGeometry(width, height);
size.IgnoreAspectRatio = maintainAspectRatio;
imgStream.Crop(size);
Crop will always use the specified width and height in Magick.NET/ImageMagick so there is no need to set size.IgnoreAspectRatio. If you want to cut out a specific area in the center of your image you should use another overload of Crop that also has a Gravity as an argument:
imgStream.Crop(width, height, Gravity.Center);
If the size variable is an instance of MagickGeometry, than there should be an X & Y offset property. I'm not familiar with .net, but I would imagine it would be something like...
MagickGeometry size = new MagickGeometry(width, height);
size.IgnoreAspectRatio = maintainAspectRatio;
// Adjust geometry offset to center of image (same as `-gravity Center`)
size.Y = imgStream.Height / 2 - height / 2;
size.X = imgStream.Width / 2 - width / 2;
imgStream.Crop(size);
I use an image view:
#IBOutlet weak var imageView: UIImageView!
to paint an image and also another image which has been rotated. It turns out that the rotated image has very bad quality. In the following image the glasses in the yellow box are not rotated. The glasses in the red box are rotated by 4.39 degrees.
Here is the code I use to draw the glasses:
UIGraphicsBeginImageContext(imageView.image!.size)
imageView.image!.drawInRect(CGRectMake(0, 0, imageView.image!.size.width, imageView.image!.size.height))
var drawCtxt = UIGraphicsGetCurrentContext()
var glassImage = UIImage(named: "glasses.png")
let yellowRect = CGRect(...)
CGContextSetStrokeColorWithColor(drawCtxt, UIColor.yellowColor().CGColor)
CGContextStrokeRect(drawCtxt, yellowRect)
CGContextDrawImage(drawCtxt, yellowRect, glassImage!.CGImage)
// paint the rotated glasses in the red square
CGContextSaveGState(drawCtxt)
CGContextTranslateCTM(drawCtxt, centerX, centerY)
CGContextRotateCTM(drawCtxt, 4.398 * CGFloat(M_PI) / 180)
var newRect = yellowRect
newRect.origin.x = -newRect.size.width / 2
newRect.origin.y = -newRect.size.height / 2
CGContextAddRect(drawCtxt, newRect)
CGContextSetStrokeColorWithColor(drawCtxt, UIColor.redColor().CGColor)
CGContextSetLineWidth(drawCtxt, 1)
// draw the red rect
CGContextStrokeRect(drawCtxt, newRect)
// draw the image
CGContextDrawImage(drawCtxt, newRect, glassImage!.CGImage)
CGContextRestoreGState(drawCtxt)
How can I rotate and paint the glasses without losing quality or get a distorted image?
You should use UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale) to create the initial context. Passing in 0.0 as the scale will default to the scale of the current screen (e.g., 2.0 on an iPhone 6 and 3.0 on an iPhone 6 Plus).
See this note on UIGraphicsBeginImageContext():
This function is equivalent to calling the UIGraphicsBeginImageContextWithOptions function with the opaque parameter set to NO and a scale factor of 1.0.
As others have pointed out, you need to set up your context to allow for retina displays.
Aside from that, you might want to use a source image that is larger than the target display size and scale it down. (2X the pixel dimensions of the target image would be a good place to start.)
Rotating to odd angles is destructive. The graphics engine has to map a grid of source pixels onto a different grid where they don't line up. Perfectly straight lines in the source image are no longer straight in the destination image, etc. The graphics engine has to do some interpolation, and a source pixel might be spread over several pixels, or less than a full pixel, in the destination image.
By providing a larger source image you give the graphics engine more information to work with. It can better slice and dice those source pixels into the destination grid of pixels.
I rotated the image from the left to the image on the right using
image = cv2.warpAffine(image, R, dst_size, flags=cv2.INTER_LINEAR)
where dst_size is (547, 363), and I've modified R so that the original image should fit in the new dimensions.
I show the image with cv2.imshow('rect post-rotation', img) to show the image on the right. You can see that it appears clipped to a size of (363, 547), even though when I print out the img shape, I get (547, 363, 3).
Why does the shape of the image not reflect the shape of the displayed image?
you need to set the destination size to the rotated size ie:
cv::Size dst_size(imOrig.size().height,imOrig.size().width);
alternatively you can use transpose and flip for 90 degree rotation:
cv::Mat imRot90 = imOrig.t();
cv::flip(imRot90 ,imRot90 ,1);
cheers
When you have to display a series of visual components (sprites) within the context of a game each taking a literal height and width that needs to be relative to the height & width of the Viewport (not necessarily aspect ratio) of the target device:
Is there a scaling class to help come up with scaling ratio in a dynamic fashion based on current device viewport size?
Will I need to roll my own scaling ratio algorithm?
Any cross platform issues I should be aware of?
This is not a question relating to the loading of assets based on target device nor is it a question of how to perform the scaling of the sprite (which is described here: http://msdn.microsoft.com/en-us/library/bb194913.aspx), rather a question of how to determine the scale of sprites based on view port size.
You can always create your own implementation of scaling.
For example, the default target viewport dimensions are:
const int defaultWidth = 1280, defaultHeight = 720;
And your current screen dimensions are 800×600, which gives you a (let's use a Vector2 instead of two floats):
int currentWidth = GraphicsDevice.Viewport.Width,
currentHeight = GraphicsDevice.Viewport.Height;
Vector2 scale = new Vector2(currentWidth / defaultWidth,
currentHeight / defaultHeight);
This gives you a {0.625; 0.83333}. You can now use this in a handy SpriteBatch.Draw() overload that takes a Vector2 scaling variable:
public void Draw (
Texture2D texture,
Vector2 position,
Nullable<Rectangle> sourceRectangle,
Color color,
float rotation,
Vector2 origin,
Vector2 scale,
SpriteEffects effects,
float layerDepth
)
Alternatively, you can draw all your stuff to a RenderTarget2D and copy the resulting image from there to a stretched texture on the main screen, but that will still require the above SpriteBatch.Draw() overload, though it might save you time if you have lots of draw calls.
Another Option to generate the scale would be to leverage:
var scaleMatrix = Matrix.CreateScale(
(float)GraphicsDevice.Viewport.Width / View.Width,
(float)GraphicsDevice.Viewport.Width / View.Width, 1f);
http://msdn.microsoft.com/en-gb/library/bb195692.aspx.
But this did not meet my needs, as I would then have to roll my own transform to map touch input location to the 'transformed' sprites (which respond to user touch input by knowing their own position and size).
In the end I used a percentage based approach.
I basically got the viewport height and width...
GraphicsDevice.Viewport.Width
GraphicsDevice.Viewport.Height
...then calculated the Height and Width of my sprites (Note: "as mentioned in question they take a literal height and width") based on their relative size to the screen myself using percentages.
//I want the buttons height and width to be 20% of the viewport
var x, y = GraphicsDevice.Viewport.Width * 0.2f; //20% of screen width
var btnsize = new Vector(x,y);
var button = new GameButton(btnsize);
Then once I have the size of the button I am able to calculate the position on the screen to render the button based of the size of the button and the available viewport size, against working in relative position based in percentages.