I have a gallery-like component, and the important part is:
<Gallery>
<Header>
<img src={galleryIcon} alt='Galley icon' />
<h1>My Gallery</h1>
</Header>
<Images isImage={custom.length > 0}>
{custom.length > 0 &&
custom.map((c, i) => (
<img
id={`custom${i}`}
key={`custom${i}`}
src={c.img}
alt='brick'
onClick={() => (setEdit((prev) => !prev), setActual(c))}
/>
))}
<div className='add'>
<button onClick={() => setGallery((prev) => !prev)}>
<img src={add} alt='Add icon' />
</button>
<p>Click to add a brick from our collections!</p>
</div>
</Images>
</Gallery>
Each image have this style:
img {
box-sizing: border-box;
height: 28vh;
width: 28vh;
margin-right: 1.5rem;
cursor: pointer;
}
Also, once the user input a new image I resize to no break the scale, with this function:
export function resizeImage(
file: File | Blob,
maxWidth: number,
maxHeight: number,
scale = 1
): Promise<Blob> {
return new Promise<Blob>((fulfill, reject) => {
const image = new Image();
image.src = URL.createObjectURL(file);
image.onload = () => {
URL.revokeObjectURL(image.src);
const width = image.width;
const height = image.height;
if (width <= maxWidth && height <= maxHeight) {
fulfill(file);
}
let newWidth = 0;
let newHeight = 0;
if (scale !== 1) {
newWidth = (width * scale) / maxWidth;
newHeight = (height * scale) / maxHeight;
} else if (width > height) {
newHeight = height * (maxWidth / width);
newWidth = maxWidth;
} else {
newWidth = width * (maxHeight / height);
newHeight = maxHeight;
}
console.log(newWidth, newHeight);
const canvas = document.createElement('canvas');
canvas.width = newWidth;
canvas.height = newHeight;
const context = canvas.getContext('2d');
context?.drawImage(image, 0, 0, newWidth, newHeight);
canvas.toBlob((blob) => blob && fulfill(blob), file.type);
};
image.onerror = reject;
});
}
And finally, the Resize component:
const Resize: React.FC<Props> = ({ actual, setResize, setCustom, custom }) => {
let stats: Stats = {} as Stats;
const getStats = useCallback((): Stats => stats, []);
const updateStats = useCallback(
(newStats: Stats): Stats => (stats = newStats),
[]
);
const getResizedCustom = useCallback(
async (copy: Custom): Promise<Custom> => {
const actualWidth = window.innerWidth;
const actualHeight = window.innerHeight;
const maxWidth = actualWidth < 1152 ? 180 : 360;
const maxHeight = actualHeight < 800 ? 180 : 360;
const newBlob = await resizeImage(
copy.blob,
maxWidth,
maxHeight,
getStats().scale
);
return {
blob: newBlob,
img: URL.createObjectURL(newBlob),
id: copy.id,
type: 'custom',
price: copy.price,
amount: copy.amount,
};
},
[stats]
);
const updateActual = useCallback(async () => {
// remove actual
const newCustomArr = [...custom];
const customCopy = newCustomArr.splice(newCustomArr.indexOf(actual), 1)[0];
const newCustom = await getResizedCustom(customCopy);
console.log(customCopy);
console.log(newCustom);
setCustom([...newCustomArr, newCustom]);
}, [actual, custom, setCustom, getResizedCustom]);
return (
<Container>
<Header>
<h1>ADJUST YOUR BRICK</h1>
<img
src={close}
alt='close icon'
onClick={() => setResize((prev) => !prev)}
/>
</Header>
<Main>
<h2>Pinch and zoom</h2>
<TransformWrapper onZoomChange={updateStats}>
<TransformComponent>
<img src={actual.img} alt='brick' />
</TransformComponent>
</TransformWrapper>
<button
onClick={async () => (
await updateActual(), setResize((prev) => !prev)
)}
>
DONE
</button>
</Main>
</Container>
);
};
I'm also using the react-zoom-pan-pinch to have the ability to zoom in and out the image. My question is: How I could resize the image on the DOM, based on the scale provided by the onZoomChange function from TransformWrapper component? Is that possible? There's a better and less "hacky" way to resize a image on DOM based on a zoom scale?
I'll try to provide a minimum repo soon, but for now, here's the full repo: https://github.com/Mdsp9070/brickart/tree/dev
It is for sure possible, but you need to be passing more props to drawImage. Check out the docs. It has four more optional arguments that you're not using. If you just use the first four then the whole image is included. When using all eight props, the first four refer to what portion of the original image to use (the cropping) while the next four specify where to put that selection of the the image on your canvas.
You need to do some math and some event tracking to calculate the source rectangle based on the center of the zoom and the scale.
Related
I am trying to resize the product images by keeping the aspect ratio and written the following function that will return the width & height. Currently it does not render the Card.Img tag element.
export default function SingleProduct({ prod }) {
const calculateAspectRatioFit = (image) => {
const maxWidth = 200; const maxHeight = 200;
let img = new Image();
img.src = image;
img.onload = function () {
var ratio = Math.min(maxWidth / this.width, maxHeight / this.height);
return (<Card.Img variant="top" src={image} style={{ width: `${this.width * ratio}`, height: `${this.height * ratio}` }} />)
};
}
return (
<div className="products">
<Card>
{calculateAspectRatioFit(prod.thumbnail)}
</Card>
</div>
)
}
I know it's something related to callback. How to resolve this?
I am working on an app which the app is intented to capture/load an image, then get the correct color from the touched coordinate on that image / camera view. (Similar to iOS's Swatches app)
The libraries I am using is react-native-camera, react-native-get-pixel-color and react-native-draggable .
There is some logic issue I'm stucked on currently....and I have researched from online and still lost in the jungle
Ratio of every devices is not same so I could not have hardcoded on the ratio, based on the document stated that the ratio is only available for android but not for iOS (default will be 4:3 for android if not defined any). So I'm thinking is it better to not to set it ? Rely on pictureSize better ? Or can without both ? Any advices is welcome...
The part which I'm quite confusing now is on the calculation part, I wanted to get the correct part of the image's color, despite different ratio , device's screen size and image size:
Live view - always get from the center
Still view - based on draggable and get the coordinates
renderCamView = () => {
if (this.state.isEnabled) {
return (
<Image
source={{ uri: this.state.liveImg.data.uri }}
style={styles.imgPreview}
/>
);
} else {
return (
<RNCamera
ref={(ref) => {
this.camera = ref;
console.log('isref');
}}
onCameraReady={()=> this.getCamData()}
style={{
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
backgroundColor: colors.black
}}
type={RNCamera.Constants.Type.back}
flashMode={this.getFlashMode()}
exposure={this.state.camera.exposure}
whiteBalance={this.state.camera.whiteBalance}
//ratio={'1:1'}
// pictureSize={this.state.pictureSize}
captureAudio={false}
androidCameraPermissionOptions={{
title: 'Permission to use camera',
message: 'We need your permission to use your camera',
buttonPositive: 'Ok',
buttonNegative: 'Cancel',
}}
/>
);
}
};
renderCenterView = () => {
if(this.state.isEnabled){
const { liveImg, mainView } = this.state;
return <Draggable
x={(this.state.mainView.width/2)-20} y={(this.state.mainView.height/2)-20}
isCircle
onShortPressRelease={this.captureColor}
onDragRelease={this.onDragEvt}
minX={0}
minY={0}
maxX={this.state.mainView.width}
maxY={this.state.mainView.height}
>
<View
style={{ width:50, height:50,borderWidth:15, borderRadius: 50, borderColor:'#d1c1b6', opacity: 0.8 }}></View>
</Draggable>
}else{
return <TouchableOpacity
onPress={this.captureColor}
style={[styles.middlePoint, { top:(this.state.mainView.height/2)-20, left:(this.state.mainView.width/2)-20 }]}/>
}
}
// Logic on Draggable, to find the coordinates on image view
onDragEvt = (event, gestureState, bounds) => {
let sourceWidth = this.state.liveImg.width;
let sourceHeight = this.state.liveImg.height;
// Find view dimensions
let width = this.state.mainView.width;
let height = this.state.mainView.height;
// Assuming image has been scaled to the smaller dimension to fit, calculate the scale
let wScale = width / sourceWidth;
let hScale = height / sourceHeight;
let scale = Math.min(wScale, hScale);
// Find the offset in the direction the image doesn't fill the screen
// For ImageViews that wrap the content, both offsets will be 0 so this is redundant
let offsetX = 0;
let offsetY = 0;
if (wScale <= hScale) {
offsetY = height / 2 - (scale * sourceHeight) / 2;
} else {
offsetX = width / 2 - (scale * sourceWidth) / 2;
}
// Convert event coordinates to image coordinates
let sourceX = (gestureState.moveX - offsetX) / scale;
let sourceY = (gestureState.moveY - offsetY) / scale;
if (sourceX < 0) {
sourceX = 0;
} else if (sourceX > sourceWidth) {
sourceX = sourceWidth - 5;
}
if (sourceY < 0) {
sourceY = 0;
} else if (sourceY > sourceHeight) {
sourceY = sourceHeight - 5;
}
this.setState({ dragView: { x: sourceX, y: sourceY } });
};
getPixelByPercentage(percentage, widthOrHeight) {
return (percentage / 100) * widthOrHeight;
}
getPixel(imageData, x, y) {
try {
GetPixelColor.setImage(isIOS ? imageData.uri : imageData.base64).catch(
(err) => {
// Handle errors
console.error(err);
},
);
GetPixelColor.pickColorAt(x, y)
.then((color) => {
// from react-native-get-pixel-color
// 'color' return as HEX
})
.catch((err) => {
// Handle errors
console.error(err);
});
} catch (e) {}
}
captureColor = async () => {
if (this.state.isEnabled) {
// live view
const { dragView, liveImg } = this.state;
if (Object.keys(dragView).length !== 0) {
let sourceX = dragView.x;
let sourceY = dragView.y;
this.getPixel(liveImg.data, sourceX, sourceY);
} else {
let getPiX = this.getPixelByPercentage(50, liveImg.width);
let getPiY = this.getPixelByPercentage(50, liveImg.height);
this.getPixel(liveImg.data, getPiX, getPiY);
}
} else {
if (this.camera) {
const data = await this.camera.takePictureAsync(CAM_OPTIONS);
await Image.getSize(data.uri, (width, height) => {
console.log('W: ', width);
console.log('H: ', height);
this.setState({
capImage: {
data: data,
imageBase64: data.base64,
width: width,
height: height,
},
});
}).then((res) => {
const { capImage } = this.state;
let getPiX = this.getPixelByPercentage(50, capImage.width);
let getPiY = this.getPixelByPercentage(50, capImage.height);
this.getPixel(capImage.data, getPiX, getPiY);
});
}
}
};
NOTES:
1. renderCamView() - render either Camera or Image
2. renderCenterView() - render the center item, either is draggable in 'still' view or fixed touchable button in 'live' view to always get the center point
3. onDragEvt() - the Draggable's event to keep track the draggable item's movement
4. this.state.mainView - the state that holds width and height of the root <View /> of this screen
5. captureColor() - onPress event to get the pixel color
6. this.state.isEnabled - define it is still view / live view
Live view - (Camera view)
Still view - (Capture and display as image / image select from album)
*Sorry for my bad English, if there is any confusing part please let me know
I am capturing images through react-webcam package but it is in a horizontal manner.
I am trying to view the image in a vertical manner. so I want the captured image to rotate at 90 degrees.
capture image is using a method that is this.webcam.getScreenshot().
so I am trying to set properties in this method so that the captured image is in a vertical manner, that it is rotated at 90 degrees.
I tried rotating the preview and capturing the image whereas, that doesn't work.
as images still are in a horizontal manner.
I want to rotate the image on capture
I tried // imageSrc.css('transform','rotate(90deg)');
but that does not work.
the image is captured as a base64 image
here webcam is the preview and capture button gets triggered by a button
capture = () => {
const imageSrc = this.webcam.getScreenshot();
this.setState({
picsArray: [...this.state.picsArray, imageSrc],
})
};
expected result: The picture is rotated 90 degrees on capturing the image using this method.
actual result: The image is not rotated at 90 degrees and doesn't know how to do it on capture.
Thank you for your time.
import React, { Component } from 'react';
import { render } from 'react-dom';
import Webcam from "react-webcam";
class App extends Component {
state = {
url: '',
};
setRef = webcam => {
this.webcam = webcam;
};
capture = () => {
const imageSrc = this.webcam.getScreenshot();
this.rotateImage(imageSrc, 180, (url) => {
this.setState({ url});
console.log(url, imageSrc);
});
};
rotateImage = (imageBase64, rotation, cb) => {
var img = new Image();
img.src = imageBase64;
img.onload = () => {
var canvas = document.createElement("canvas");
// var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.setTransform(1, 0, 0, 1, img.width / 2, img.height / 2);
ctx.rotate(rotation * (Math.PI / 180));
ctx.drawImage(img, -img.width / 2, -img.height / 2);
cb(canvas.toDataURL("image/jpeg"))
};
};
render() {
const videoConstraints = {
width: 1280,
height: 720,
facingMode: "user"
};
return (
<div>
<Webcam
audio={false}
height={350}
ref={this.setRef}
screenshotFormat="image/jpeg"
width={350}
videoConstraints={videoConstraints}
/>
<button onClick={this.capture}>Capture photo</button>
<img src={this.state.url} width="200" height="100" />
<canvas id="canvas" style={{display: 'none'}}></canvas>
</div>
);
}
}
render(<App />, document.getElementById('root'));
Update
Below code work for any dimension, only need to adjust in this.dim to reflect your need
import React, { Component } from 'react';
import { render } from 'react-dom';
import Webcam from "react-webcam";
class App extends Component {
state = {
url: '',
};
dim = {
height: 300, // adjust your original height
width: 200, // adjust your original width
};
setRef = webcam => {
this.webcam = webcam;
};
capture = () => {
const imageSrc = this.webcam.getScreenshot();
this.rotateImage(imageSrc, (url) => {
this.setState({ url});
console.log(url, imageSrc);
});
};
rotateImage = (imageBase64, cb) => {
var img = new Image();
img.src = imageBase64;
img.onload = () => {
var canvas = document.createElement("canvas");
const maxDim = Math.max(img.height, img.width);
canvas.width = img.height;
canvas.height = img.width;
var ctx = canvas.getContext("2d");
ctx.setTransform(1, 0, 0, 1, maxDim / 2, maxDim / 2);
ctx.rotate(90 * (Math.PI / 180));
ctx.drawImage(img, -maxDim / 2, -maxDim / 2);
cb(canvas.toDataURL("image/jpeg"))
};
};
render() {
const videoConstraints = {
width: this.dim.width,
height: this.dim.height,
facingMode: "user"
};
return (
<div>
<Webcam
audio={false}
height={this.dim.height}
ref={this.setRef}
screenshotFormat="image/jpeg"
width={this.dim.width}
videoConstraints={videoConstraints}
/>
<button onClick={this.capture}>Capture photo</button>
<img src={this.state.url} width={this.dim.height} height={this.dim.width} />
<canvas id="canvas" style={{display: 'none'}}></canvas>
</div>
);
}
}
render(<App />, document.getElementById('root'));
You can rotate the image immediately in the preview using the style property:
90:
<Webcam style={{ transformOrigin: '0 0', transform: `translateX(${(480 + 640) / 2}px) rotate(90deg)` }} /> // height + width
180:
<Webcam style={{transform: 'rotate(180deg)'}} />,
270:
<Webcam style={{ transformOrigin: '0 0', transform: `translate(${(480 - 640) / 2}px, ${480}px) rotate(-90deg)` }} />
You should put your base64 image in an img tag in this way:
<img src="data:image/png;base64, YOUR_BASE_64" />
and then apply the CSS transform that you mentioned the img.
I am trying to crop an image before uploading it through an API. I am showing a modal (Dialog) to do this, and using this library react-image-crop to achieve this.
Here is the code snippet:
showCropImageModal() {
const actions = [
<FlatButton
label="Cancel"
primary={true}
onClick={this.handleCancel}
/>,
<FlatButton
label="Crop"
primary={true}
keyboardFocused={true}
onClick={this.handleCropClose}
/>,
];
if (this.state.showImageCropper) {
return (
<div>
<Dialog
title="Crop the image"
actions={actions}
modal={true}
open={this.state.showImageCropper}
autoScrollBodyContent={true}
>
<ReactCrop
src={this.state.selectedImageURL}
crop={this.state.crop}
onComplete={(crop, pixel) => {console.log(crop, pixel)}}
onChange={(crop) => { console.log(crop); this.setState({crop}); }}
/>
</Dialog>
</div>
);
}
}
On "Crop" action I am handling it using the handleCropClose function:
handleCropClose(){
let {selectedFile, crop} = this.state
const croppedImg = this.getCroppedImg(selectedFile, crop.width, crop.height, crop.x, crop.y, 2);
console.log(croppedImg)
this.setState({showImageCropper: false})
}
And here is getCroppedImg code:
getCroppedImg(imgObj, newWidth, newHeight, startX, startY, ratio) {
/* the parameters: - the image element - the new width - the new height - the x point we start taking pixels - the y point we start taking pixels - the ratio */
// Set up canvas for thumbnail
console.log(imgObj)
var img = new Image();
img.src = this.state.selectedImageURL;
var tnCanvas = this.refs.canvas;
tnCanvas.width = newWidth;
tnCanvas.height = newHeight;
tnCanvas.getContext('2d').drawImage(img, startX, startY, newWidth, newHeight);
return tnCanvas.toDataURL("image/png");
}
Now, I am not able to get the right preview or new image file object so that I could use that to show as preview in the modal there itself and than use the same to upload it. I am not even getting the right image ratio. Any help?
Here is the image:
react-image-crop using percent for scaling, make sure to calculate. Also make sure while create new object image on the fly to render virtual dom.
Here, try this:
import React, { Component } from 'react';
import ReactCrop, { makeAspectCrop } from 'react-image-crop';
import { FlatButton, Dialog } from 'material-ui';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import sample from './sample.png';
import 'react-image-crop/dist/ReactCrop.css';
class App extends Component {
state = {
showImageCropper: false,
selectedImageURL: sample,
crop: {
x: 0,
y: 0,
// aspect: 16 / 9,
},
selectedFile: null,
croppedImage: sample
};
showCropImageModal() {
const actions = [
<FlatButton
label="Cancel"
primary={true}
onClick={this.handleCancel}
/>,
<FlatButton
label="Crop"
primary={true}
keyboardFocused={true}
onClick={this.handleCropClose}
/>,
];
if (this.state.showImageCropper) {
return (
<div>
<Dialog
title="Crop the image"
actions={actions}
modal={true}
open={this.state.showImageCropper}
autoScrollBodyContent={true}
>
<ReactCrop
src={this.state.selectedImageURL}
crop={this.state.crop}
// onImageLoaded={this.onImageLoaded}
onComplete={this.onCropComplete}
onChange={this.onCropChange}
/>
</Dialog>
</div>
);
}
}
onCropComplete = (crop, pixels) => {
}
onCropChange = (crop) => {
this.setState({ crop });
}
// onImageLoaded = (image) => {
// this.setState({
// crop: makeAspectCrop({
// x: 0,
// y: 0,
// // aspect: 10 / 4,
// // width: 50,
// }, image.naturalWidth / image.naturalHeight),
// image,
// });
// }
handleCancel = () => {
this.setState({ showImageCropper: false });
}
handleCropClose = () => {
let { crop } = this.state;
// console.log("selectedFile", selectedFile);
// console.log("crop",crop);
const croppedImg = this.getCroppedImg(this.refImageCrop, crop);
this.setState({ showImageCropper: false, croppedImage: croppedImg })
}
getCroppedImg(srcImage,pixelCrop) {
/* the parameters: - the image element - the new width - the new height - the x point we start taking pixels - the y point we start taking pixels - the ratio */
// Set up canvas for thumbnail
// console.log(imgObj);
// let img = new Image();
// img.src = this.state.selectedImageURL;
// let tempCanvas = document.createElement('canvas');
// let tnCanvas = tempCanvas;
// tnCanvas.width = newWidth;
// tnCanvas.height = newHeight;
// tnCanvas.getContext('2d').drawImage(img, startX, startY, newWidth, newHeight);
// return tnCanvas;
let img = new Image();
img.src = this.state.selectedImageURL;
const targetX = srcImage.width * pixelCrop.x / 100;
const targetY = srcImage.height * pixelCrop.y / 100;
const targetWidth = srcImage.width * pixelCrop.width / 100;
const targetHeight = srcImage.height * pixelCrop.height / 100;
const canvas = document.createElement('canvas');
canvas.width = targetWidth;
canvas.height = targetHeight;
const ctx = canvas.getContext('2d');
ctx.drawImage(
img,
targetX,
targetY,
targetWidth,
targetHeight,
0,
0,
targetWidth,
targetHeight
);
return canvas.toDataURL('image/jpeg');
}
handleOpen = () => {
this.setState({ showImageCropper: true });
}
render() {
return (
<MuiThemeProvider>
<div className="App">
{ this.showCropImageModal() }
<img src={this.state.selectedImageURL} style={{display: "none"}} ref={(img) => {this.refImageCrop = img}} alt="" />
<img src={this.state.croppedImage} alt="" />
<FlatButton
label="Open popup"
primary={true}
onClick={this.handleOpen}
/>
</div>
</MuiThemeProvider>
);
}
}
export default App;
Solution :
First, use pixel coordinates:
- change : onChange={(crop) => { console.log(crop); this.setState({crop}); }}
- to onChange={(crop, pixelCrop) => { console.log(crop); this.setState({crop, pixelCrop}); }}.
Use this.state.pixelCrop instead of this.state.crop for getCroppedImg.
Then, update getCroppedImg to fetch the image asynchronously using a Promise and crop it.
getCroppedImg(imgObj, newWidth, newHeight, startX, startY, ratio) {
/* the parameters: - the image element - the new width - the new height - the x point we start taking pixels - the y point we start taking pixels - the ratio */
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = resolve;
img.onerror = reject;
img.src = this.state.selectedImageURL;
}).then(img => {
// Set up canvas for thumbnail
var tnCanvas = this.refs.canvas;
tnCanvas.width = newWidth;
tnCanvas.height = newHeight;
tnCanvas
.getContext('2d')
.drawImage(
img,
startX, startY, newWidth, newHeight,
0, 0, newWidth, newHeight
);
return tnCanvas.toDataURL("image/png");
});
}
Explanation :
You are missing parameters to drawImage. You are asking the canvas to draw the image at position (startX, startY) and scale it to (newWidth, newHeight).
To crop the image you need additional parameters :
drawImage(
image,
sx, sy, sw, sh,
dx, dy, dw, dh
);
Where :
Example :
const img = new Image()
const canvas = document.createElement('canvas')
img.src = 'https://cmeimg-a.akamaihd.net/640/clsd/getty/991dda07ecb947f1834bf1aa89153cf6'
const newWidth = 200
const newHeight = 200
const startX = 200
const startY = 100
img.onload = () => {
canvas.width = newWidth;
canvas.height = newHeight;
canvas.getContext('2d').drawImage(img, startX, startY, newWidth, newHeight, 0, 0, newWidth, newHeight);
}
document.body.appendChild(canvas)
document.body.appendChild(img)
this is my function where am calculating image's height and width, but I had to use react native's image. getSizebut this has a callback which a has a delay somehow and the return brock seems to execute before this image. getSize finish.
renderNode (node, index, siblings, parent, defaultRenderer) {
let finalwidth ;
let finalheight;
if (node.name === 'img') {
const a = node.attribs;
Image.getSize(a.src, (width, height) => {
let screenSize = Dimensions.get('window');
let hRatio = screenSize.width / width;
let vRatio = screenSize.height / height;
let ratio = Math.max(hRatio, vRatio);
let rat = hRatio / vRatio;
finalwidth = parseInt(width * ratio);
finalheight = parseInt(height * ratio);
alert(finalwidth + 'x' + finalheight) // they have values here
})
return (
<Image
key={index}
source={{uri: a.src}}
resizeMode={'stretch'}
style={{
width: finalwidth, //finalwidth is null here
height:finalheight, //finalheight is null here
}}
/>
);
}
}
Actually, I want to access the value of final width and final height in my return brock
use setState() and set those values into state so that the component is rerendered when the data is updated
constructor(props){
super(props);
this.state={finalwidth : null,
finalheight: null
}
}
renderNode (node, index, siblings, parent, defaultRenderer) {
if (node.name === 'img') {
const a = node.attribs;
Image.getSize(a.src, (width, height) => {
let screenSize = Dimensions.get('window');
let hRatio = screenSize.width / width;
let vRatio = screenSize.height / height;
let ratio = Math.max(hRatio, vRatio);
let rat = hRatio / vRatio;
finalwidth = parseInt(width * ratio);
finalheight = parseInt(height * ratio);
this.setState({finalwidth, finalheight})
alert(finalwidth + 'x' + finalheight) // they have values here
})
return (
<Image
key={index}
source={{uri: a.src}}
resizeMode={'stretch'}
style={{
width: this.state.finalwidth, //finalwidth from state
height: this.state.finalheight, //finalheight from state
}}
/>
);
}
}