2010-06-09 37 views
9

Tôi có một ứng dụng mà người dùng cuối có thể định kích thước và định vị hình ảnh trong một nhà thiết kế. Kể từ khi các cuộc gọi spec cho hình ảnh được "kéo dài" để kiểm soát có chứa, người dùng cuối có thể kết thúc với một hình ảnh kéo dài awkwardly.Cách "thay đổi kích cỡ thông minh" hình ảnh hiển thị thành tỷ lệ khung hình gốc

Để giúp người dùng định kích thước hình ảnh, tôi đang nghĩ đến việc triển khai chức năng chỉnh sửa thông minh, cho phép người dùng dễ dàng sửa tỷ lệ cỡ ảnh để không còn bị kéo dài.

Cách nhanh chóng để giải quyết điều này là thực sự cung cấp hai tùy chọn: 1) tỷ lệ từ chiều rộng 2) tỷ lệ từ chiều cao. Người dùng chọn phương pháp và thuật toán điều chỉnh kích thước của hình ảnh bằng cách sử dụng tỷ lệ khung hình gốc. Ví dụ: Hình ảnh được hiển thị là 200x200 trên thiết kế nhưng hình ảnh gốc là 1024x768 pixel. Người dùng chọn "Kích thước thông minh từ chiều rộng" và kích thước mới trở thành ~ 200x150 vì tỷ lệ khung hình gốc là ~ 1.333

OK, nhưng làm cách nào để làm cho thuật toán trở nên thông minh hơn và không làm phiền người dùng nên dựa trên?

Trả lời

22

Nếu tôi giải thích spec của bạn một cách chính xác, bạn muốn có một kết quả đó là không lớn hơn so với một người dùng cuối đặt ra ban đầu; bạn muốn một trong hai kích thước co lại và phần còn lại giữ nguyên. Nói cách khác, kích thước mới sẽ lấp đầy không gian thiết kế theo một hướng trong khi rút ngắn kích thước theo hướng khác để giữ nguyên tỷ lệ khung hình gốc.

original_ratio = original_width/original_height 
designer_ratio = designer_width/designer_height 
if original_ratio > designer_ratio 
    designer_height = designer_width/original_ratio 
else 
    designer_width = designer_height * original_ratio 

Thường thì bạn sẽ làm việc với tọa độ nguyên, nhưng các phân đoạn để tạo tỷ lệ trên cần phải là dấu phẩy động. Đây là một sắp xếp lại của công thức để có nhiều số nguyên thân thiện. Đảm bảo các số nguyên của bạn có phạm vi để xử lý chiều rộng * chiều cao tối đa.

if original_width * designer_height > designer_width * original_height 
    designer_height = (designer_width * original_height)/original_width 
else 
    designer_width = (designer_height * original_width)/original_height 
+0

Có, thông số kỹ thuật cần phải được mở rộng để xác định những gì thay đổi kích thước thông minh thực sự. Thuật toán này nghe có vẻ hợp lý. Tôi sẽ thử nó. –

1

Tính kích thước mới cho cả hai biến thể ("tỷ lệ theo chiều rộng" và "tỷ lệ theo chiều cao"), sau đó sử dụng thứ nguyên phù hợp trong màn hình.

Hoặc bạn cũng có thể tính tỷ lệ khung hình của "hộp giới hạn" và so sánh tỷ lệ khung hình với tỷ lệ co của hình ảnh gốc. Tùy thuộc vào tỷ lệ khung hình nào lớn hơn, chiều cao hoặc chiều rộng cần phải được thu nhỏ.

Bạn cũng có thể hạn chế quy trình thay đổi kích thước để trong mọi trường hợp "chia tỷ lệ theo chiều rộng" được thực hiện. Sau đó, để thay đổi kích thước của hình ảnh, người dùng luôn phải thay đổi chiều rộng của hình ảnh. Chiều cao sẽ luôn được điều chỉnh tự động.

+0

Tôi đã suy nghĩ dọc những dòng nhưng làm thế nào để yhou xác định những gì là quá rộng hoặc quá cao khi người dùng có thể tùy ý kích thước và đặt hình ảnh ? –

+0

@Paul: Nó có bị giới hạn ở mức 200x200 không? Chức năng kích thước thông minh hiện tại có được giới hạn từ đâu? – sth

+0

chúng tôi sắp kết thúc. Các giới hạn được thiết lập ngầm bởi người dùng bằng cách thao tác với kích thước hình ảnh. Xem trả lời của tôi để khnle dưới đây. –

1

Vì bạn muốn tối đa hóa hiển thị hình ảnh được chia tỷ lệ càng lớn càng tốt trong cửa sổ của bạn, tức là khu vực trong nhà thiết kế của bạn, bạn sẽ lấy chiều rộng hoặc chiều cao của hình ảnh gốc hơn, và quy mô mà đến 200. Pseudo-code (chiều rộng, chiều cao là kích thước của bản gốc):

if (width > height) { 
    scaledWidth = 200; 
    scaledHeight = (height * 200)/width; 
} else { 
    scaledHeight = 200; 
    scaledWidth = (width * 200)/height; 
} 
+0

Không. Tôi muốn hình ảnh có kích thước gần với những gì người dùng đã đặt ra càng nhiều càng tốt. Cuối cùng, một trong các kích thước sẽ không thay đổi. –

0

Bạn chỉ cần làm việc ra các quy mô cần thiết cho cả kích thước và sau đó lấy nhỏ hơn của 2.

2

Không có kế toán với số tiền là sao chép và pasters ngoài kia eh! Tôi cũng muốn biết điều này và tất cả những gì tôi thấy là những ví dụ vô tận về chiều rộng chiều rộng HOẶC chiều cao .. ai sẽ muốn người khác tràn?

  • rộng Thay đổi kích thước và chiều cao mà không cần một vòng lặp
  • Không vượt quá những hình ảnh kích thước ban đầu
  • Sử dụng toán học mà làm việc đúng cách tức là chiều rộng/khía cạnh cho chiều cao, và chiều cao * khía cạnh cho chiều rộng nên hình ảnh được thực tế qua cân đúng cách lên xuống:/

//////////////

private void ResizeImage(Image img, double maxWidth, double maxHeight) 
{ 
    double srcWidth = img.Source.Width; 
    double srcHeight = img.Source.Height; 

    double resizeWidth = srcWidth; 
    double resizeHeight = srcHeight; 

    double aspect = resizeWidth/resizeHeight; 

    if (resizeWidth > maxWidth) 
    { 
     resizeWidth = maxWidth; 
     resizeHeight = resizeWidth/aspect; 
    } 
    if (resizeHeight > maxHeight) 
    { 
     aspect = resizeWidth/resizeHeight; 
     resizeHeight = maxHeight; 
     resizeWidth = resizeHeight * aspect; 
    } 

    img.Width = resizeWidth; 
    img.Height = resizeHeight; 
} 
+0

khá tốt, ngoại trừ khi bạn thực hiện ResizeImage (i, 2000,3000) –

6

Dưới đây là một giải pháp tôi đã đưa ra khi phải giải quyết vấn đề này. Hóa ra khá ngắn và đơn giản, chỉ muốn chia sẻ nó.

Handy "công thức": ratio = W/HW = H * ratio

  1. Tính tỷ lệ.
  2. Tính chiều cao của hình ảnh nếu bạn đặt chiều rộng thành chiều rộng kích thước mới (chiều rộng cho phép tối đa).
  3. Tính chiều rộng của hình ảnh nếu bạn đặt chiều cao thành chiều cao kích thước mới (chiều cao tối đa cho phép).
  4. Xem kích thước nào trong hai kích thước không ghi đè kích thước tối đa trong bất kỳ thứ nguyên nào. Nếu tỷ lệ không phải là 1 trong số chúng sẽ luôn sai và một sẽ luôn đúng.

Trong Javascript

// Returns array with new width and height 
function proportionalScale(originalSize, newSize) 
{ 
    var ratio = originalSize[0]/originalSize[1]; 

    var maximizedToWidth = [newSize[0], newSize[0]/ratio]; 
    var maximizedToHeight = [newSize[1] * ratio, newSize[1]]; 

    if (maximizedToWidth[1] > newSize[1]) { return maximizedToHeight; } 
    else { return maximizedToWidth; } 
} 

originalSizenewSize là một mảng [0] = width, [1] = height

2

Đã đề nghị trên và làm cho nó mở rộng lên/xuống trong vòng tối đa chiều cao/chiều rộng. Đây là mã python cho nó và cũng hỗ trợ cho việc xoay các thứ trong khi vẫn giữ trong giới hạn:

def _resize (hình ảnh, kích thước, xoay = Không): "" " Thay đổi kích thước hình ảnh càng gần càng tốt Hình ảnh là một hình ảnh django-model-field.

Will both scale up and down the image to meet this while keeping the proportions 
    in width and height 

""" 

if image and os.path.isfile(image.path): 

    im = pil.open(image.path) 
    logging.debug('resizing image from %s x %s --> %s x %s ' % (im.size[0], im.size[1], dimensions[0], dimensions[1])) 

    if rotate: 
     logging.debug('first rotating image %s' % rotate) 
     im = im.rotate(90) 

    srcWidth = Decimal(im.size[0]) 
    srcHeight = Decimal(im.size[1]) 

    resizeWidth = srcWidth 
    resizeHeight = srcHeight 

    aspect = resizeWidth/resizeHeight # Decimal 

    logging.debug('resize aspect is %s' % aspect) 

    if resizeWidth > dimensions[0] or resizeHeight > dimensions[1]: 
     # if width or height is bigger we need to shrink things 
     if resizeWidth > dimensions[0]: 
      resizeWidth = Decimal(dimensions[0]) 
      resizeHeight = resizeWidth/aspect 

     if resizeHeight > dimensions[1] : 
      aspect = resizeWidth/resizeHeight 
      resizeHeight = Decimal(dimensions[1]) 
      resizeWidth = resizeHeight * aspect 

    else: 
     # if both width and height are smaller we need to increase size 
     if resizeWidth < dimensions[0]: 
      resizeWidth = Decimal(dimensions[0]) 
      resizeHeight = resizeWidth/aspect 

     if resizeHeight > dimensions[1] : 
      aspect = resizeWidth/resizeHeight 
      resizeHeight = Decimal(dimensions[1]) 
      resizeWidth = resizeHeight * aspect 

    im = im.resize((resizeWidth, resizeHeight), pil.ANTIALIAS) 

    logging.debug('resized image to %s %s' % im.size) 
    im.save(image.path) 

else: 
    # no action, due to no image or no image in path 
    pass 

return image 
0

đây là giải pháp của tôi,

a = khía cạnh sw = gốc ảnh rộng sh = gốc chiều cao hình ảnh dw = yêu cầu tối đa chiều rộng dh = yêu cầu chiều cao tối đa

sw và sh sẽ chứa các giá trị được đổi kích thước cuối cùng

mã là PHP:

$a = $sw/$sh; 

if($a > 1){ 
    // wider image 
    if($sw != $dw){ 
     $rt = $dw/$sw; 
     $sw = $sw * $rt; 
     $sh = $sh * $rt; 
    } 

    if($sh > $dh){ 
     $rt = $dh/$sh; 
     $sw = $sw * $rt; 
     $sh = $sh * $rt; 
    } 
}else{ 
    // taller image 
    if($sh != $dh){ 
     $rt = $dh/$sh; 
     $sh = $sh * $rt; 
     $sw = $sw * $rt; 
    } 

    if($sw > $dw){ 
     $rt = $dw/$sw; 
     $sh = $sh * $rt; 
     $sw = $sw * $rt; 
    } 
} 
0

tôi đã sử dụng cách này để thay đổi kích thước hình ảnh để FHD cách

if (width >= height) { 
    var original_ratio = width/height 
    new_width = 1080 * original_ratio 
    console.log("new new_width = " + Math.round(new_width)); 
    console.log("new new_height = 1080"); 
} else { 
    var original_ratio = height/width 
    new_height = 1080 * original_ratio 
    console.log("new new_height = " + Math.round(new_height)); 
    console.log("new new_width = 1080"); 
} 

bạn có thể thay đổi 1080 với kích thước mới.

Tôi hy vọng nó hữu ích cho ai đó ít nhất.

0

Giải pháp của tôi để thu nhỏ và phát triển kích thước trong javascript dựa trên https://stackoverflow.com/a/5654847/1055015

var scale = function (srcWidth, srcHeight, maxWidth, maxHeight) { 

     let resizeWidth = srcWidth; 
     let resizeHeight = srcHeight; 

     let aspect = resizeWidth/resizeHeight; 
     let scaleX = maxWidth/srcWidth; 
     let scaleY = maxHeight/srcHeight; 
     let scale = Math.min(scaleX, scaleY); 

     resizeWidth *= scale; 
     resizeHeight *= scale; 

     if (resizeWidth > maxWidth) { 
     resizeWidth = maxWidth; 
     resizeHeight = resizeWidth/aspect; 
     } 

     if (resizeHeight > maxHeight) { 
     aspect  = resizeWidth/resizeHeight; 
     resizeHeight = maxHeight; 
     resizeWidth = resizeHeight * aspect; 
     } 

     return { 
     width : resizeWidth, 
     height: resizeHeight, 
     }; 
    } 
Các vấn đề liên quan